MIPS: Change inlined cache of intanceof stub to use indirection through cell.
Port r10380 (46f646). Original commit message: The stub was directly patching caller's code without issuing write barrier which violated incremental marking invariants. BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/9159008 Patch from Daniel Kalmar <kalmard@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10457 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
4de11a7bee
commit
1f4ec772f7
@ -4252,7 +4252,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
|
|||||||
const Register inline_site = t5;
|
const Register inline_site = t5;
|
||||||
const Register scratch = a2;
|
const Register scratch = a2;
|
||||||
|
|
||||||
const int32_t kDeltaToLoadBoolResult = 4 * kPointerSize;
|
const int32_t kDeltaToLoadBoolResult = 5 * kPointerSize;
|
||||||
|
|
||||||
Label slow, loop, is_instance, is_not_instance, not_js_object;
|
Label slow, loop, is_instance, is_not_instance, not_js_object;
|
||||||
|
|
||||||
@ -4296,11 +4296,12 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
|
|||||||
// Patch the (relocated) inlined map check.
|
// Patch the (relocated) inlined map check.
|
||||||
|
|
||||||
// The offset was stored in t0 safepoint slot.
|
// The offset was stored in t0 safepoint slot.
|
||||||
// (See LCodeGen::DoDeferredLInstanceOfKnownGlobal)
|
// (See LCodeGen::DoDeferredLInstanceOfKnownGlobal).
|
||||||
__ LoadFromSafepointRegisterSlot(scratch, t0);
|
__ LoadFromSafepointRegisterSlot(scratch, t0);
|
||||||
__ Subu(inline_site, ra, scratch);
|
__ Subu(inline_site, ra, scratch);
|
||||||
// Patch the relocated value to map.
|
// Get the map location in scratch and patch it.
|
||||||
__ PatchRelocatedValue(inline_site, scratch, map);
|
__ GetRelocatedValue(inline_site, scratch, v1); // v1 used as scratch.
|
||||||
|
__ sw(map, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register mapping: a3 is object map and t0 is function prototype.
|
// Register mapping: a3 is object map and t0 is function prototype.
|
||||||
|
@ -2019,7 +2019,10 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
|
|||||||
// We use Factory::the_hole_value() on purpose instead of loading from the
|
// We use Factory::the_hole_value() on purpose instead of loading from the
|
||||||
// root array to force relocation to be able to later patch with
|
// root array to force relocation to be able to later patch with
|
||||||
// the cached map.
|
// the cached map.
|
||||||
__ li(at, Operand(factory()->the_hole_value()), true);
|
Handle<JSGlobalPropertyCell> cell =
|
||||||
|
factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
|
||||||
|
__ li(at, Operand(Handle<Object>(cell)));
|
||||||
|
__ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset));
|
||||||
__ Branch(&cache_miss, ne, map, Operand(at));
|
__ Branch(&cache_miss, ne, map, Operand(at));
|
||||||
// We use Factory::the_hole_value() on purpose instead of loading from the
|
// We use Factory::the_hole_value() on purpose instead of loading from the
|
||||||
// root array to force relocation to be able to later patch
|
// root array to force relocation to be able to later patch
|
||||||
|
@ -4747,6 +4747,34 @@ void MacroAssembler::PatchRelocatedValue(Register li_location,
|
|||||||
FlushICache(li_location, 2);
|
FlushICache(li_location, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::GetRelocatedValue(Register li_location,
|
||||||
|
Register value,
|
||||||
|
Register scratch) {
|
||||||
|
lw(value, MemOperand(li_location));
|
||||||
|
if (emit_debug_code()) {
|
||||||
|
And(value, value, kOpcodeMask);
|
||||||
|
Check(eq, "The instruction should be a lui.",
|
||||||
|
value, Operand(LUI));
|
||||||
|
lw(value, MemOperand(li_location));
|
||||||
|
}
|
||||||
|
|
||||||
|
// value now holds a lui instruction. Extract the immediate.
|
||||||
|
sll(value, value, kImm16Bits);
|
||||||
|
|
||||||
|
lw(scratch, MemOperand(li_location, kInstrSize));
|
||||||
|
if (emit_debug_code()) {
|
||||||
|
And(scratch, scratch, kOpcodeMask);
|
||||||
|
Check(eq, "The instruction should be an ori.",
|
||||||
|
scratch, Operand(ORI));
|
||||||
|
lw(scratch, MemOperand(li_location, kInstrSize));
|
||||||
|
}
|
||||||
|
// "scratch" now holds an ori instruction. Extract the immediate.
|
||||||
|
andi(scratch, scratch, kImm16Mask);
|
||||||
|
|
||||||
|
// Merge the results.
|
||||||
|
or_(value, value, scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::CheckPageFlag(
|
void MacroAssembler::CheckPageFlag(
|
||||||
Register object,
|
Register object,
|
||||||
|
@ -1328,6 +1328,10 @@ class MacroAssembler: public Assembler {
|
|||||||
void PatchRelocatedValue(Register li_location,
|
void PatchRelocatedValue(Register li_location,
|
||||||
Register scratch,
|
Register scratch,
|
||||||
Register new_value);
|
Register new_value);
|
||||||
|
// Get the relocatad value (loaded data) from the lui/ori pair.
|
||||||
|
void GetRelocatedValue(Register li_location,
|
||||||
|
Register value,
|
||||||
|
Register scratch);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CallCFunctionHelper(Register function,
|
void CallCFunctionHelper(Register function,
|
||||||
|
Loading…
Reference in New Issue
Block a user