CpuProfiler: x87. put right address to the stack, so the callee would be able to resolve it into the right deopt_info.
'from' is using for Code object lookup and will be used for inline_id lookup. see https://codereview.chromium.org/1012633002 So we should be able to map it. BUG=chromium:452067 LOG=n Review URL: https://codereview.chromium.org/1013243002 Cr-Commit-Position: refs/heads/master@{#27251}
This commit is contained in:
parent
45434d575e
commit
549d5dde6a
@ -374,10 +374,11 @@ void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
|
||||
|
||||
|
||||
bool LCodeGen::GenerateJumpTable() {
|
||||
if (!jump_table_.length()) return !is_aborted();
|
||||
|
||||
Label needs_frame;
|
||||
if (jump_table_.length() > 0) {
|
||||
Comment(";;; -------------------- Jump table --------------------");
|
||||
}
|
||||
Comment(";;; -------------------- Jump table --------------------");
|
||||
|
||||
for (int i = 0; i < jump_table_.length(); i++) {
|
||||
Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i];
|
||||
__ bind(&table_entry->label);
|
||||
@ -386,34 +387,56 @@ bool LCodeGen::GenerateJumpTable() {
|
||||
if (table_entry->needs_frame) {
|
||||
DCHECK(!info()->saves_caller_doubles());
|
||||
__ push(Immediate(ExternalReference::ForDeoptEntry(entry)));
|
||||
if (needs_frame.is_bound()) {
|
||||
__ jmp(&needs_frame);
|
||||
} else {
|
||||
__ bind(&needs_frame);
|
||||
__ push(MemOperand(ebp, StandardFrameConstants::kContextOffset));
|
||||
// This variant of deopt can only be used with stubs. Since we don't
|
||||
// have a function pointer to install in the stack frame that we're
|
||||
// building, install a special marker there instead.
|
||||
DCHECK(info()->IsStub());
|
||||
__ push(Immediate(Smi::FromInt(StackFrame::STUB)));
|
||||
// Push a PC inside the function so that the deopt code can find where
|
||||
// the deopt comes from. It doesn't have to be the precise return
|
||||
// address of a "calling" LAZY deopt, it only has to be somewhere
|
||||
// inside the code body.
|
||||
Label push_approx_pc;
|
||||
__ call(&push_approx_pc);
|
||||
__ bind(&push_approx_pc);
|
||||
// Push the continuation which was stashed were the ebp should
|
||||
// be. Replace it with the saved ebp.
|
||||
__ push(MemOperand(esp, 3 * kPointerSize));
|
||||
__ mov(MemOperand(esp, 4 * kPointerSize), ebp);
|
||||
__ lea(ebp, MemOperand(esp, 4 * kPointerSize));
|
||||
__ ret(0); // Call the continuation without clobbering registers.
|
||||
}
|
||||
__ call(&needs_frame);
|
||||
} else {
|
||||
__ call(entry, RelocInfo::RUNTIME_ENTRY);
|
||||
}
|
||||
}
|
||||
if (needs_frame.is_linked()) {
|
||||
__ bind(&needs_frame);
|
||||
|
||||
/* stack layout
|
||||
4: entry address
|
||||
3: return address <-- esp
|
||||
2: garbage
|
||||
1: garbage
|
||||
0: garbage
|
||||
*/
|
||||
__ sub(esp, Immediate(kPointerSize)); // Reserve space for stub marker.
|
||||
__ push(MemOperand(esp, kPointerSize)); // Copy return address.
|
||||
__ push(MemOperand(esp, 3 * kPointerSize)); // Copy entry address.
|
||||
|
||||
/* stack layout
|
||||
4: entry address
|
||||
3: return address
|
||||
2: garbage
|
||||
1: return address
|
||||
0: entry address <-- esp
|
||||
*/
|
||||
__ mov(MemOperand(esp, 4 * kPointerSize), ebp); // Save ebp.
|
||||
|
||||
// Copy context.
|
||||
__ mov(ebp, MemOperand(ebp, StandardFrameConstants::kContextOffset));
|
||||
__ mov(MemOperand(esp, 3 * kPointerSize), ebp);
|
||||
// Fill ebp with the right stack frame address.
|
||||
__ lea(ebp, MemOperand(esp, 4 * kPointerSize));
|
||||
|
||||
// This variant of deopt can only be used with stubs. Since we don't
|
||||
// have a function pointer to install in the stack frame that we're
|
||||
// building, install a special marker there instead.
|
||||
DCHECK(info()->IsStub());
|
||||
__ mov(MemOperand(esp, 2 * kPointerSize),
|
||||
Immediate(Smi::FromInt(StackFrame::STUB)));
|
||||
|
||||
/* stack layout
|
||||
4: old ebp
|
||||
3: context pointer
|
||||
2: stub marker
|
||||
1: return address
|
||||
0: entry address <-- esp
|
||||
*/
|
||||
__ ret(0); // Call the continuation without clobbering registers.
|
||||
}
|
||||
return !is_aborted();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user