Load API holder from prototype chain instead embedding it in handler.
authorulan <ulan@chromium.org>
Thu, 29 Jan 2015 17:18:41 +0000 (09:18 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 29 Jan 2015 17:18:50 +0000 (17:18 +0000)
BUG=v8:3629
LOG=N

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

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

src/ic/arm/handler-compiler-arm.cc
src/ic/arm64/handler-compiler-arm64.cc
src/ic/call-optimization.cc
src/ic/call-optimization.h
src/ic/ia32/handler-compiler-ia32.cc
src/ic/mips/handler-compiler-mips.cc
src/ic/mips64/handler-compiler-mips64.cc
src/ic/x64/handler-compiler-x64.cc
src/ic/x87/handler-compiler-x87.cc

index b990a94b934e210e55cc0d9d1333dddcbe3ea5dd..d0db7904c858270797ea88716c9f373e40c43755 100644 (file)
@@ -266,14 +266,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ Move(holder, api_holder);
+      __ ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
+        __ ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
index 87edcd269a871824ca8ebde3c1b3ae0525404e1a..3a6d156943aa8f4e1f23224ffccd2ca81608aa01 100644 (file)
@@ -178,14 +178,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Mov(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ LoadObject(holder, api_holder);
+      __ Ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ Ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
+        __ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
index 065b1472eb66c3cb8e4a8ac241099b77b032a623..5377988d1166fc10ba62f6a8485f809291bf116f 100644 (file)
@@ -16,7 +16,8 @@ CallOptimization::CallOptimization(Handle<JSFunction> function) {
 
 
 Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
-    Handle<Map> object_map, HolderLookup* holder_lookup) const {
+    Handle<Map> object_map, HolderLookup* holder_lookup,
+    int* holder_depth_in_prototype_chain) const {
   DCHECK(is_simple_api_call());
   if (!object_map->IsJSObjectMap()) {
     *holder_lookup = kHolderNotFound;
@@ -27,13 +28,16 @@ Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
     *holder_lookup = kHolderIsReceiver;
     return Handle<JSObject>::null();
   }
-  while (true) {
+  for (int depth = 1; true; depth++) {
     if (!object_map->prototype()->IsJSObject()) break;
     Handle<JSObject> prototype(JSObject::cast(object_map->prototype()));
     if (!prototype->map()->is_hidden_prototype()) break;
     object_map = handle(prototype->map());
     if (expected_receiver_type_->IsTemplateFor(*object_map)) {
       *holder_lookup = kHolderFound;
+      if (holder_depth_in_prototype_chain != NULL) {
+        *holder_depth_in_prototype_chain = depth;
+      }
       return prototype;
     }
   }
index 99494fa3bad8b7747734dc7f38844c8fe50c3aed..b6435d25a3e30aa2f440e8775e69710a963a7a0a 100644 (file)
@@ -38,7 +38,8 @@ class CallOptimization BASE_EMBEDDED {
 
   enum HolderLookup { kHolderNotFound, kHolderIsReceiver, kHolderFound };
   Handle<JSObject> LookupHolderOfExpectedType(
-      Handle<Map> receiver_map, HolderLookup* holder_lookup) const;
+      Handle<Map> receiver_map, HolderLookup* holder_lookup,
+      int* holder_depth_in_prototype_chain = NULL) const;
 
   // Check if the api holder is between the receiver and the holder.
   bool IsCompatibleReceiver(Handle<Object> receiver,
index c7f683fd5b60f8f2400ba9888bebd4a90d6d5582..65adbff48eb683766c22b9425a50d199f3e9dd12 100644 (file)
@@ -175,14 +175,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ LoadHeapObject(holder, api_holder);
+      __ mov(holder, FieldOperand(receiver, HeapObject::kMapOffset));
+      __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ mov(holder, FieldOperand(holder, HeapObject::kMapOffset));
+        __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
index 1a8aadcf8018387c014481cd06d9502481280c43..b02179b4a35f180940265e044e6302025d389776 100644 (file)
@@ -259,14 +259,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ li(holder, api_holder);
+      __ lw(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ lw(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ lw(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
+        __ lw(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
index e82073fe76c504dd52fe2c44615e1eef9c2f146e..5e7814c8154ba45c7fabbd820092d8b6f28b3f35 100644 (file)
@@ -260,14 +260,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ li(holder, api_holder);
+      __ ld(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ ld(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
+        __ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
index ce621777eafa61422f5e2ba596ca1aeb6201b87f..cdc5b5e38cda59d6a53934aab75452b96c7b0306 100644 (file)
@@ -161,14 +161,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ Move(holder, api_holder);
+      __ movp(holder, FieldOperand(receiver, HeapObject::kMapOffset));
+      __ movp(holder, FieldOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ movp(holder, FieldOperand(holder, HeapObject::kMapOffset));
+        __ movp(holder, FieldOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();
index 11e727c081efb47a97f2dc6e422d88155d01853d..1110410771d2d277c65dfe5a251b5952bcdf690d 100644 (file)
@@ -175,14 +175,20 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
 
   // Put holder in place.
   CallOptimization::HolderLookup holder_lookup;
-  Handle<JSObject> api_holder =
-      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  int holder_depth = 0;
+  optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
+                                          &holder_depth);
   switch (holder_lookup) {
     case CallOptimization::kHolderIsReceiver:
       __ Move(holder, receiver);
       break;
     case CallOptimization::kHolderFound:
-      __ LoadHeapObject(holder, api_holder);
+      __ mov(holder, FieldOperand(receiver, HeapObject::kMapOffset));
+      __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
+      for (int i = 1; i < holder_depth; i++) {
+        __ mov(holder, FieldOperand(holder, HeapObject::kMapOffset));
+        __ mov(holder, FieldOperand(holder, Map::kPrototypeOffset));
+      }
       break;
     case CallOptimization::kHolderNotFound:
       UNREACHABLE();