[mips] InterpreterEntryTrampoline improvement
Logic is added to InterpreterEntryTrampoline to detect flushed functions,
and enter CompileLazy instead. Get the bytecode array from the function
object and load it. The bytecode array could have been flushed from the
shared function info, if so, call into CompileLazy.
This fixes:
cctest/test-heap/TestBytecodeFlushing
cctest/test-heap/TestOptimizeAfterBytecodeFlushingCandidate
debugger/debug/lazy-deopt-then-flush-bytecode
[mips] Macro-assembler fix
Fix massive failing of tests after fa3cbf6
.
Change-Id: Ic1978b5233eefc743fd7b020f65153630ffa281f
Reviewed-on: https://chromium-review.googlesource.com/c/1388528
Reviewed-by: Sreten Kovacevic <skovacevic@wavecomp.com>
Commit-Queue: Sreten Kovacevic <skovacevic@wavecomp.com>
Cr-Commit-Position: refs/heads/master@{#58463}
This commit is contained in:
parent
d7493fb1ab
commit
0f1b611277
@ -1012,6 +1012,19 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
Register closure = a1;
|
Register closure = a1;
|
||||||
Register feedback_vector = a2;
|
Register feedback_vector = a2;
|
||||||
|
|
||||||
|
// Get the bytecode array from the function object and load it into
|
||||||
|
// kInterpreterBytecodeArrayRegister.
|
||||||
|
__ lw(a0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||||
|
__ lw(kInterpreterBytecodeArrayRegister,
|
||||||
|
FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
||||||
|
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, t0);
|
||||||
|
|
||||||
|
// The bytecode array could have been flushed from the shared function info,
|
||||||
|
// if so, call into CompileLazy.
|
||||||
|
Label compile_lazy;
|
||||||
|
__ GetObjectType(kInterpreterBytecodeArrayRegister, a0, a0);
|
||||||
|
__ Branch(&compile_lazy, ne, a0, Operand(BYTECODE_ARRAY_TYPE));
|
||||||
|
|
||||||
// Load the feedback vector from the closure.
|
// Load the feedback vector from the closure.
|
||||||
__ lw(feedback_vector,
|
__ lw(feedback_vector,
|
||||||
FieldMemOperand(closure, JSFunction::kFeedbackCellOffset));
|
FieldMemOperand(closure, JSFunction::kFeedbackCellOffset));
|
||||||
@ -1026,12 +1039,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
||||||
__ PushStandardFrame(closure);
|
__ PushStandardFrame(closure);
|
||||||
|
|
||||||
// Get the bytecode array from the function object and load it into
|
|
||||||
// kInterpreterBytecodeArrayRegister.
|
|
||||||
__ lw(a0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
|
||||||
__ lw(kInterpreterBytecodeArrayRegister,
|
|
||||||
FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
|
||||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, t0);
|
|
||||||
|
|
||||||
// Increment invocation count for the function.
|
// Increment invocation count for the function.
|
||||||
__ lw(t0, FieldMemOperand(feedback_vector,
|
__ lw(t0, FieldMemOperand(feedback_vector,
|
||||||
@ -1040,18 +1047,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
__ sw(t0, FieldMemOperand(feedback_vector,
|
__ sw(t0, FieldMemOperand(feedback_vector,
|
||||||
FeedbackVector::kInvocationCountOffset));
|
FeedbackVector::kInvocationCountOffset));
|
||||||
|
|
||||||
// Check function data field is actually a BytecodeArray object.
|
|
||||||
if (FLAG_debug_code) {
|
|
||||||
__ SmiTst(kInterpreterBytecodeArrayRegister, t0);
|
|
||||||
__ Assert(ne,
|
|
||||||
AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
|
|
||||||
t0, Operand(zero_reg));
|
|
||||||
__ GetObjectType(kInterpreterBytecodeArrayRegister, t0, t0);
|
|
||||||
__ Assert(eq,
|
|
||||||
AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
|
|
||||||
t0, Operand(BYTECODE_ARRAY_TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset code age.
|
// Reset code age.
|
||||||
DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge);
|
DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge);
|
||||||
__ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
__ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||||
@ -1145,6 +1140,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
// The return value is in v0.
|
// The return value is in v0.
|
||||||
LeaveInterpreterFrame(masm, t0);
|
LeaveInterpreterFrame(masm, t0);
|
||||||
__ Jump(ra);
|
__ Jump(ra);
|
||||||
|
|
||||||
|
__ bind(&compile_lazy);
|
||||||
|
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||||
|
// Unreachable code.
|
||||||
|
__ break_(0xCC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||||
|
@ -1005,6 +1005,19 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
Register closure = a1;
|
Register closure = a1;
|
||||||
Register feedback_vector = a2;
|
Register feedback_vector = a2;
|
||||||
|
|
||||||
|
// Get the bytecode array from the function object and load it into
|
||||||
|
// kInterpreterBytecodeArrayRegister.
|
||||||
|
__ Ld(a0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||||
|
__ Ld(kInterpreterBytecodeArrayRegister,
|
||||||
|
FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
||||||
|
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, a4);
|
||||||
|
|
||||||
|
// The bytecode array could have been flushed from the shared function info,
|
||||||
|
// if so, call into CompileLazy.
|
||||||
|
Label compile_lazy;
|
||||||
|
__ GetObjectType(kInterpreterBytecodeArrayRegister, a0, a0);
|
||||||
|
__ Branch(&compile_lazy, ne, a0, Operand(BYTECODE_ARRAY_TYPE));
|
||||||
|
|
||||||
// Load the feedback vector from the closure.
|
// Load the feedback vector from the closure.
|
||||||
__ Ld(feedback_vector,
|
__ Ld(feedback_vector,
|
||||||
FieldMemOperand(closure, JSFunction::kFeedbackCellOffset));
|
FieldMemOperand(closure, JSFunction::kFeedbackCellOffset));
|
||||||
@ -1019,13 +1032,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
||||||
__ PushStandardFrame(closure);
|
__ PushStandardFrame(closure);
|
||||||
|
|
||||||
// Get the bytecode array from the function object and load it into
|
|
||||||
// kInterpreterBytecodeArrayRegister.
|
|
||||||
__ Ld(a0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
|
||||||
__ Ld(kInterpreterBytecodeArrayRegister,
|
|
||||||
FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
|
||||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, a4);
|
|
||||||
|
|
||||||
// Increment invocation count for the function.
|
// Increment invocation count for the function.
|
||||||
__ Lw(a4, FieldMemOperand(feedback_vector,
|
__ Lw(a4, FieldMemOperand(feedback_vector,
|
||||||
FeedbackVector::kInvocationCountOffset));
|
FeedbackVector::kInvocationCountOffset));
|
||||||
@ -1033,18 +1039,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
__ Sw(a4, FieldMemOperand(feedback_vector,
|
__ Sw(a4, FieldMemOperand(feedback_vector,
|
||||||
FeedbackVector::kInvocationCountOffset));
|
FeedbackVector::kInvocationCountOffset));
|
||||||
|
|
||||||
// Check function data field is actually a BytecodeArray object.
|
|
||||||
if (FLAG_debug_code) {
|
|
||||||
__ SmiTst(kInterpreterBytecodeArrayRegister, a4);
|
|
||||||
__ Assert(ne,
|
|
||||||
AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
|
|
||||||
a4, Operand(zero_reg));
|
|
||||||
__ GetObjectType(kInterpreterBytecodeArrayRegister, a4, a4);
|
|
||||||
__ Assert(eq,
|
|
||||||
AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
|
|
||||||
a4, Operand(BYTECODE_ARRAY_TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset code age.
|
// Reset code age.
|
||||||
DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge);
|
DCHECK_EQ(0, BytecodeArray::kNoAgeBytecodeAge);
|
||||||
__ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
__ sb(zero_reg, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||||
@ -1139,6 +1133,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
|||||||
// The return value is in v0.
|
// The return value is in v0.
|
||||||
LeaveInterpreterFrame(masm, t0);
|
LeaveInterpreterFrame(masm, t0);
|
||||||
__ Jump(ra);
|
__ Jump(ra);
|
||||||
|
|
||||||
|
__ bind(&compile_lazy);
|
||||||
|
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||||
|
// Unreachable code.
|
||||||
|
__ break_(0xCC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||||
|
@ -3980,9 +3980,8 @@ void TurboAssembler::CallBuiltinPointer(Register builtin_pointer) {
|
|||||||
STATIC_ASSERT(kSmiTag == 0);
|
STATIC_ASSERT(kSmiTag == 0);
|
||||||
|
|
||||||
// The builtin_pointer register contains the builtin index as a Smi.
|
// The builtin_pointer register contains the builtin index as a Smi.
|
||||||
// Untagging is folded into the indexing operand below.
|
SmiUntag(builtin_pointer, builtin_pointer);
|
||||||
Lsa(builtin_pointer, kRootRegister, builtin_pointer,
|
Lsa(builtin_pointer, kRootRegister, builtin_pointer, kSystemPointerSizeLog2);
|
||||||
kSystemPointerSize - kSmiTagSize);
|
|
||||||
lw(builtin_pointer,
|
lw(builtin_pointer,
|
||||||
MemOperand(builtin_pointer, IsolateData::builtin_entry_table_offset()));
|
MemOperand(builtin_pointer, IsolateData::builtin_entry_table_offset()));
|
||||||
Call(builtin_pointer);
|
Call(builtin_pointer);
|
||||||
|
@ -4308,7 +4308,7 @@ void TurboAssembler::CallBuiltinPointer(Register builtin_pointer) {
|
|||||||
|
|
||||||
// The builtin_pointer register contains the builtin index as a Smi.
|
// The builtin_pointer register contains the builtin index as a Smi.
|
||||||
SmiUntag(builtin_pointer, builtin_pointer);
|
SmiUntag(builtin_pointer, builtin_pointer);
|
||||||
Lsa(builtin_pointer, kRootRegister, builtin_pointer, kSystemPointerSizeLog2);
|
Dlsa(builtin_pointer, kRootRegister, builtin_pointer, kSystemPointerSizeLog2);
|
||||||
Ld(builtin_pointer,
|
Ld(builtin_pointer,
|
||||||
MemOperand(builtin_pointer, IsolateData::builtin_entry_table_offset()));
|
MemOperand(builtin_pointer, IsolateData::builtin_entry_table_offset()));
|
||||||
Call(builtin_pointer);
|
Call(builtin_pointer);
|
||||||
|
Loading…
Reference in New Issue
Block a user