MIPS: Cache IC handlers on the prototype's map if possible.
authorbalazs.kilvady@imgtec.com <balazs.kilvady@imgtec.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 18 Jul 2014 17:11:52 +0000 (17:11 +0000)
committerbalazs.kilvady@imgtec.com <balazs.kilvady@imgtec.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 18 Jul 2014 17:11:52 +0000 (17:11 +0000)
Port r22483 (6dd09cb)

Original commit message:
Instead of on the receiver's map. Lazily overwrite cached handler if it is
identical to the handler that just missed.

BUG=
R=akos.palfi@imgtec.com

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

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

src/mips/ic-mips.cc
src/mips/stub-cache-mips.cc
src/mips64/ic-mips64.cc
src/mips64/stub-cache-mips64.cc

index 23ad6de..4ae0be2 100644 (file)
@@ -283,7 +283,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   ASSERT(name.is(a2));
 
   // Probe the stub cache.
-  Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::LOAD_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
       masm, flags, receiver, name, a3, t0, t1, t2);
 
@@ -1105,7 +1106,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   ASSERT(ValueRegister().is(a0));
 
   // Get the receiver from the stack and probe the stub cache.
-  Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
       masm, flags, receiver, name, a3, t0, t1, t2);
 
index 7fada54..5b66a7e 100644 (file)
@@ -885,12 +885,15 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      if (heap()->InNewSpace(*prototype)) {
-        // The prototype is in new space; we cannot store a reference to it
-        // in the code.  Load it from the map.
+      // Two possible reasons for loading the prototype from the map:
+      // (1) Can't store references to new space in code.
+      // (2) Handler is shared for all receivers with the same prototype
+      //     map (but not necessarily the same prototype instance).
+      bool load_prototype_from_map =
+          heap()->InNewSpace(*prototype) || depth == 1;
+      if (load_prototype_from_map) {
         __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
       } else {
-        // The prototype is in old space; load it directly.
         __ li(reg, Operand(prototype));
       }
     }
index 17241d6..49d9c4a 100644 (file)
@@ -283,7 +283,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   ASSERT(name.is(a2));
 
   // Probe the stub cache.
-  Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::LOAD_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
       masm, flags, receiver, name, a3, a4, a5, a6);
 
@@ -1114,7 +1115,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   ASSERT(ValueRegister().is(a0));
 
   // Get the receiver from the stack and probe the stub cache.
-  Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
       masm, flags, receiver, name, a3, a4, a5, a6);
 
index 39ae974..82f4696 100644 (file)
@@ -865,6 +865,12 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
       reg = holder_reg;  // From now on the object will be in holder_reg.
       __ ld(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
     } else {
+      // Two possible reasons for loading the prototype from the map:
+      // (1) Can't store references to new space in code.
+      // (2) Handler is shared for all receivers with the same prototype
+      //     map (but not necessarily the same prototype instance).
+      bool load_prototype_from_map =
+          heap()->InNewSpace(*prototype) || depth == 1;
       Register map_reg = scratch1;
       if (depth != 1 || check == CHECK_ALL_MAPS) {
         // CheckMap implicitly loads the map of |reg| into |map_reg|.
@@ -886,12 +892,9 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      if (heap()->InNewSpace(*prototype)) {
-        // The prototype is in new space; we cannot store a reference to it
-        // in the code.  Load it from the map.
+      if (load_prototype_from_map) {
         __ ld(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
       } else {
-        // The prototype is in old space; load it directly.
         __ li(reg, Operand(prototype));
       }
     }