Speed up creation of Objects whose prototype has dictionary elements
authoradamk@chromium.org <adamk@chromium.org>
Wed, 22 Oct 2014 18:16:35 +0000 (18:16 +0000)
committeradamk@chromium.org <adamk@chromium.org>
Wed, 22 Oct 2014 18:16:35 +0000 (18:16 +0000)
This speeds up both the case from the bug (using Object.create) but also
takes care ofthe "{ __proto__: obj  }" syntax, which was previously (and
erroneously) being treated the same as setting the prototype dynamically
from script using the __proto__ setter or Object.setPrototypeOf.

BUG=chromium:422754
LOG=y
R=mvstanton@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24814 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/compiler/ast-graph-builder.cc
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/objects.cc
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/mjsunit/fast-prototype.js

index d40833f..01fa5c5 100644 (file)
@@ -1760,7 +1760,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         __ push(r0);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
index 3d3e5ee..d461833 100644 (file)
@@ -1741,7 +1741,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
           __ Peek(x0, 0);
           __ Push(x0);
           VisitForStackValue(value);
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           VisitForEffect(value);
         }
index 647a00b..50a3720 100644 (file)
@@ -942,7 +942,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
         Node* receiver = environment()->Pop();
         if (property->emit_store()) {
           const Operator* op =
-              javascript()->CallRuntime(Runtime::kSetPrototype, 2);
+              javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
           NewNode(op, receiver, value);
         }
         break;
index e2aac7f..aa9acf3 100644 (file)
@@ -1686,7 +1686,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         __ push(Operand(esp, 0));  // Duplicate receiver.
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
index 08f021f..c710dcf 100644 (file)
@@ -1746,7 +1746,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         __ push(a0);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
index 30b3fbf..b57dbb1 100644 (file)
@@ -1743,7 +1743,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         __ push(a0);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
index 47a61f6..5d85b13 100644 (file)
@@ -11796,7 +11796,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
   DCHECK(new_map->prototype() == *value);
   JSObject::MigrateToMap(real_receiver, new_map);
 
-  if (!dictionary_elements_in_chain &&
+  if (from_javascript && !dictionary_elements_in_chain &&
       new_map->DictionaryElementsInPrototypeChainOnly()) {
     // If the prototype chain didn't previously have element callbacks, then
     // KeyedStoreICs need to be cleared to ensure any that involve this
index 90df549..e6fecdd 100644 (file)
@@ -1720,7 +1720,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         __ Push(Operand(rsp, 0));  // Duplicate receiver.
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
index dac05ea..4b7e997 100644 (file)
@@ -1675,7 +1675,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         __ push(Operand(esp, 0));  // Duplicate receiver.
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
index 9864761..c59ec94 100644 (file)
@@ -114,9 +114,9 @@ for (key in x) {
   assertTrue(key == 'a');
   break;
 }
-assertFalse(%HasFastProperties(x));
+assertTrue(%HasFastProperties(x));
 x.d = 4;
-assertFalse(%HasFastProperties(x));
+assertTrue(%HasFastProperties(x));
 for (key in x) {
   assertTrue(key == 'a');
   break;