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) {
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);
......
......@@ -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);
}
}
......
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