[runtime] Remove useless DELETE builtin.
authorbmeurer <bmeurer@chromium.org>
Thu, 13 Aug 2015 09:41:36 +0000 (02:41 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 13 Aug 2015 09:41:50 +0000 (09:41 +0000)
The DELETE builtin calls through to %DeleteProperty anyway, so we
can as well skip the builtin completely and always call into the
runtime directly.  Also add different entries depending on whether
calling code is in sloppy or strict/strong mode.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1291973002

Cr-Commit-Position: refs/heads/master@{#30148}

16 files changed:
src/builtins.h
src/compiler/js-generic-lowering.cc
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/ppc/full-codegen-ppc.cc
src/full-codegen/x64/full-codegen-x64.cc
src/full-codegen/x87/full-codegen-x87.cc
src/hydrogen.cc
src/runtime.js
src/runtime/runtime-object.cc
src/runtime/runtime.h
src/v8natives.js
test/cctest/test-api.cc

index 8ced3e3b93b71b6c3f4acd186a1f96252ae88ef5..6ec618ada9b129905662187213868db4eb175973 100644 (file)
@@ -175,7 +175,6 @@ enum BuiltinExtraArguments {
   V(SAR_STRONG, 1)                         \
   V(SHR, 1)                                \
   V(SHR_STRONG, 1)                         \
-  V(DELETE, 2)                             \
   V(IN, 1)                                 \
   V(INSTANCE_OF, 1)                        \
   V(CALL_NON_FUNCTION, 0)                  \
index 0219aac670da8cae5b6e1d09713b64407097bab4..bec199e0e399f7ce34cd25516f89f9d7d93f2396 100644 (file)
@@ -430,8 +430,9 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
 
 void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
   LanguageMode language_mode = OpParameter<LanguageMode>(node);
-  ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
-  node->InsertInput(zone(), 4, jsgraph()->SmiConstant(language_mode));
+  ReplaceWithRuntimeCall(node, is_strict(language_mode)
+                                   ? Runtime::kDeleteProperty_Strict
+                                   : Runtime::kDeleteProperty_Sloppy);
 }
 
 
index b64da3a9d6be581543bd76cd4f1204dd6c2fbafe..d7a9bc3e5fc6cb4bc5be98dca3641ed22d2be982 100644 (file)
@@ -4619,9 +4619,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ mov(r1, Operand(Smi::FromInt(language_mode())));
-        __ push(r1);
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(r0);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4632,9 +4633,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ ldr(r2, GlobalObjectOperand());
           __ mov(r1, Operand(var->name()));
-          __ mov(r0, Operand(Smi::FromInt(SLOPPY)));
-          __ Push(r2, r1, r0);
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ Push(r2, r1);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(r0);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global, non-dynamic variables is false.
index dea09fcddbfc8a16c88675d7420497033da6bf85..9e73340019ed82cf503bd33927ae1b5effb9fb83 100644 (file)
@@ -4314,9 +4314,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ Mov(x10, Smi::FromInt(language_mode()));
-        __ Push(x10);
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(x0);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4327,9 +4328,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ Ldr(x12, GlobalObjectMemOperand());
           __ Mov(x11, Operand(var->name()));
-          __ Mov(x10, Smi::FromInt(SLOPPY));
-          __ Push(x12, x11, x10);
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ Push(x12, x11);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(x0);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global, non-dynamic variables is false.
index 7015691ea69bb4c5abef624c2ce922596b1bbc93..390a44be30c0acb0e922212ffd575ab76830fb35 100644 (file)
@@ -4554,8 +4554,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ push(Immediate(Smi::FromInt(language_mode())));
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(eax);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4566,8 +4568,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ push(GlobalObjectOperand());
           __ push(Immediate(var->name()));
-          __ push(Immediate(Smi::FromInt(SLOPPY)));
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(eax);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global variables is false.  'this' is
index 0e8c4a0a5b27ec75e0088a8c4b7daa190834ebd1..d3139a7d4ecf46b22cca766c416a767967aeb91d 100644 (file)
@@ -4641,9 +4641,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ li(a1, Operand(Smi::FromInt(language_mode())));
-        __ push(a1);
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(v0);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4654,9 +4655,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ lw(a2, GlobalObjectOperand());
           __ li(a1, Operand(var->name()));
-          __ li(a0, Operand(Smi::FromInt(SLOPPY)));
-          __ Push(a2, a1, a0);
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ Push(a2, a1);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(v0);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global, non-dynamic variables is false.
index fab263e3598bf18f4ca644d66eb8a5cc2b01fcd6..e8a46c3facdb05fa1a21db1194c3398473ccb6e9 100644 (file)
@@ -4643,9 +4643,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ li(a1, Operand(Smi::FromInt(language_mode())));
-        __ push(a1);
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(v0);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4656,9 +4657,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ ld(a2, GlobalObjectOperand());
           __ li(a1, Operand(var->name()));
-          __ li(a0, Operand(Smi::FromInt(SLOPPY)));
-          __ Push(a2, a1, a0);
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ Push(a2, a1);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(v0);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global, non-dynamic variables is false.
index 10dc8d66e1770739973dd6a664914882f694a881..c92d883ef50538e04a5ab26b1f4e8ab725e92eac 100644 (file)
@@ -4644,9 +4644,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ LoadSmiLiteral(r4, Smi::FromInt(language_mode()));
-        __ push(r4);
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(r3);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4657,9 +4658,8 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ LoadP(r5, GlobalObjectOperand());
           __ mov(r4, Operand(var->name()));
-          __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY));
-          __ Push(r5, r4, r3);
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ Push(r5, r4);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(r3);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global, non-dynamic variables is false.
index d351c819860a63c5d40e65a6707b58314761a227..eda5207026b8fdff1484eb837f9252ace5646311 100644 (file)
@@ -4566,8 +4566,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ Push(Smi::FromInt(language_mode()));
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(rax);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4578,8 +4580,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ Push(GlobalObjectOperand());
           __ Push(var->name());
-          __ Push(Smi::FromInt(SLOPPY));
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(rax);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global variables is false.  'this' is
index afd20396e9cb22db578bd856dbd72d80dd700c11..061954729b0add541f54d1815d6c293399bdc2ee 100644 (file)
@@ -4549,8 +4549,10 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
       if (property != NULL) {
         VisitForStackValue(property->obj());
         VisitForStackValue(property->key());
-        __ push(Immediate(Smi::FromInt(language_mode())));
-        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        __ CallRuntime(is_strict(language_mode())
+                           ? Runtime::kDeleteProperty_Strict
+                           : Runtime::kDeleteProperty_Sloppy,
+                       2);
         context()->Plug(eax);
       } else if (proxy != NULL) {
         Variable* var = proxy->var();
@@ -4561,8 +4563,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
         if (var->IsUnallocatedOrGlobalSlot()) {
           __ push(GlobalObjectOperand());
           __ push(Immediate(var->name()));
-          __ push(Immediate(Smi::FromInt(SLOPPY)));
-          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
           context()->Plug(eax);
         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
           // Result of deleting non-global variables is false.  'this' is
index 9b2a2f6a078341f7cacbc40eaec9557450444801..d5868f399f0cc02d72d497fa3309175b250d4c6c 100644 (file)
@@ -10410,11 +10410,13 @@ void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) {
     CHECK_ALIVE(VisitForValue(prop->key()));
     HValue* key = Pop();
     HValue* obj = Pop();
-    HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
-    Add<HPushArguments>(obj, key, Add<HConstant>(function_language_mode()));
-    // TODO(olivf) InvokeFunction produces a check for the parameter count,
-    // even though we are certain to pass the correct number of arguments here.
-    HInstruction* instr = New<HInvokeFunction>(function, 3);
+    Add<HPushArguments>(obj, key);
+    HInstruction* instr = New<HCallRuntime>(
+        isolate()->factory()->empty_string(),
+        Runtime::FunctionForId(is_strict(function_language_mode())
+                                   ? Runtime::kDeleteProperty_Strict
+                                   : Runtime::kDeleteProperty_Sloppy),
+        2);
     return ast_context()->ReturnInstruction(instr, expr->id());
   } else if (proxy != NULL) {
     Variable* var = proxy->var();
index e82d25e3295c745af5ee701e1166f9fdc5935aea..f7c91d3cc20e4130c4c6b20c46fe1c94483de68c 100644 (file)
@@ -44,7 +44,6 @@ var SAR;
 var SAR_STRONG;
 var SHR;
 var SHR_STRONG;
-var DELETE;
 var IN;
 var INSTANCE_OF;
 var CALL_NON_FUNCTION;
@@ -484,12 +483,6 @@ SHR_STRONG = function SHR_STRONG(y) {
    -----------------------------
 */
 
-// ECMA-262, section 11.4.1, page 46.
-DELETE = function DELETE(key, language_mode) {
-  return %DeleteProperty(TO_OBJECT(this), key, language_mode);
-}
-
-
 // ECMA-262, section 11.8.7, page 54.
 IN = function IN(x) {
   if (!IS_SPEC_OBJECT(x)) {
index b0546640df0ce604ea2aa57ecbe9a3239dffae7f..064e4c216291dc7d56261dc195a0db1d6d2f54ab 100644 (file)
@@ -671,12 +671,16 @@ RUNTIME_FUNCTION(Runtime_SetProperty) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_DeleteProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
+namespace {
+
+// ES6 section 12.5.4.
+Object* DeleteProperty(Isolate* isolate, Handle<Object> object,
+                       Handle<Object> key, LanguageMode language_mode) {
+  Handle<JSReceiver> receiver;
+  if (!JSReceiver::ToObject(isolate, object).ToHandle(&receiver)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject));
+  }
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, result,
@@ -684,6 +688,26 @@ RUNTIME_FUNCTION(Runtime_DeleteProperty) {
   return *result;
 }
 
+}  // namespace
+
+
+RUNTIME_FUNCTION(Runtime_DeleteProperty_Sloppy) {
+  HandleScope scope(isolate);
+  DCHECK_EQ(2, args.length());
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  return DeleteProperty(isolate, object, key, SLOPPY);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeleteProperty_Strict) {
+  HandleScope scope(isolate);
+  DCHECK_EQ(2, args.length());
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  return DeleteProperty(isolate, object, key, STRICT);
+}
+
 
 static Object* HasOwnPropertyImplementation(Isolate* isolate,
                                             Handle<JSObject> object,
index 62acb2275b7f47240ab856af56300c5aef5652be..cb6f89e25f40392c34df60f7b8b728acda1e0bd7 100644 (file)
@@ -450,7 +450,8 @@ namespace internal {
   F(SetProperty, 4, 1)                               \
   F(AddElement, 3, 1)                                \
   F(AppendElement, 2, 1)                             \
-  F(DeleteProperty, 3, 1)                            \
+  F(DeleteProperty_Sloppy, 2, 1)                     \
+  F(DeleteProperty_Strict, 2, 1)                     \
   F(HasOwnProperty, 2, 1)                            \
   F(HasProperty, 2, 1)                               \
   F(HasElement, 2, 1)                                \
index b950d4a274ba4b25d097cade19c9d847799212a0..0241507220ef9ea9e51038bc88ba25b0aa4ca24a 100644 (file)
@@ -590,7 +590,7 @@ function Delete(obj, p, should_throw) {
   var desc = GetOwnPropertyJS(obj, p);
   if (IS_UNDEFINED(desc)) return true;
   if (desc.isConfigurable()) {
-    %DeleteProperty(obj, p, 0);
+    %DeleteProperty_Sloppy(obj, p);
     return true;
   } else if (should_throw) {
     throw MakeTypeError(kDefineDisallowed, p);
index ecceb81943a97eec2f772c80754cc5c54d067ee5..dad5d6caf5ca1e79d4e2924b998ce52b818c89c3 100644 (file)
@@ -19293,8 +19293,10 @@ TEST(AccessCheckThrows) {
   CheckCorrectThrow("%GetProperty(other, 'x')");
   CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 0)");
   CheckCorrectThrow("%AddNamedProperty(other, 'x', 'foo', 1)");
-  CheckCorrectThrow("%DeleteProperty(other, 'x', 0)");
-  CheckCorrectThrow("%DeleteProperty(other, '1', 0)");
+  CheckCorrectThrow("%DeleteProperty_Sloppy(other, 'x')");
+  CheckCorrectThrow("%DeleteProperty_Strict(other, 'x')");
+  CheckCorrectThrow("%DeleteProperty_Sloppy(other, '1')");
+  CheckCorrectThrow("%DeleteProperty_Strict(other, '1')");
   CheckCorrectThrow("%HasOwnProperty(other, 'x')");
   CheckCorrectThrow("%HasProperty(other, 'x')");
   CheckCorrectThrow("%HasElement(other, 1)");