X87: Cache IC handlers on the prototype's map if possible

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
parent 90708659
...@@ -893,7 +893,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { ...@@ -893,7 +893,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
ASSERT(name.is(ecx)); ASSERT(name.is(ecx));
// Probe the stub cache. // 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->isolate()->stub_cache()->GenerateProbe(
masm, flags, receiver, name, ebx, eax); masm, flags, receiver, name, ebx, eax);
...@@ -1009,7 +1010,8 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { ...@@ -1009,7 +1010,8 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
// Return address is on the stack. // 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->isolate()->stub_cache()->GenerateProbe(
masm, flags, ReceiverRegister(), NameRegister(), masm, flags, ReceiverRegister(), NameRegister(),
ebx, no_reg); ebx, no_reg);
......
...@@ -822,6 +822,11 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type, ...@@ -822,6 +822,11 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
__ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
} else { } else {
bool in_new_space = heap()->InNewSpace(*prototype); 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) { if (depth != 1 || check == CHECK_ALL_MAPS) {
__ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
} }
...@@ -837,19 +842,16 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type, ...@@ -837,19 +842,16 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
scratch2, miss); scratch2, miss);
} }
if (in_new_space) { if (load_prototype_from_map) {
// Save the map in scratch1 for later. // Save the map in scratch1 for later.
__ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
} }
reg = holder_reg; // From now on the object will be in holder_reg. reg = holder_reg; // From now on the object will be in holder_reg.
if (in_new_space) { if (load_prototype_from_map) {
// The prototype is in new space; we cannot store a reference to it
// in the code. Load it from the map.
__ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
} else { } else {
// The prototype is in old space; load it directly.
__ mov(reg, prototype); __ mov(reg, prototype);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment