X87: Cache IC handlers on the prototype's map if possible
authorweiliang.lin@intel.com <weiliang.lin@intel.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Jul 2014 02:57:42 +0000 (02:57 +0000)
committerweiliang.lin@intel.com <weiliang.lin@intel.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Jul 2014 02:57:42 +0000 (02:57 +0000)
port r22483

original commit message:

  Cache IC handlers on the prototype's map if possible

  instead of on the receiver's map. Lazily overwrite cached handler if it is
  identical to the handler that just missed.

BUG=
R=weiliang.lin@intel.com

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

Patch from Chunyang Dai <chunyang.dai@intel.com>.

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

src/x87/ic-x87.cc
src/x87/stub-cache-x87.cc

index 8bf3b65501ebe762411fb23416ef0265e798428b..5db259813f05855d37f1fc889c6f222558deaa71 100644 (file)
@@ -893,7 +893,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   ASSERT(name.is(ecx));
 
   // 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, ebx, eax);
 
@@ -1009,7 +1010,8 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
 
 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
   // Return address is on the stack.
-  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, ReceiverRegister(), NameRegister(),
       ebx, no_reg);
index 98d55f2ba3d100d0badeefd18cba931665069746..f4fd75b01fe728be29b83f41ba1a90cac8e7a90b 100644 (file)
@@ -822,6 +822,11 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
     } else {
       bool in_new_space = heap()->InNewSpace(*prototype);
+      // 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 = in_new_space || depth == 1;
       if (depth != 1 || check == CHECK_ALL_MAPS) {
         __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
       }
@@ -837,19 +842,16 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
             scratch2, miss);
       }
 
-      if (in_new_space) {
+      if (load_prototype_from_map) {
         // Save the map in scratch1 for later.
         __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
       }
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      if (in_new_space) {
-        // 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) {
         __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
       } else {
-        // The prototype is in old space; load it directly.
         __ mov(reg, prototype);
       }
     }