Commit 36dfc384 authored by Liu Yu's avatar Liu Yu Committed by Commit Bot

[mips][turboprop] Add a slot for optimization marker in feedback vector

Port d7ece57e

Bug: v8:9684
Change-Id: I6b103a5331f49a248e56a72d85e79f3d0fd2ef96
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2505243
Auto-Submit: Liu yu <liuyu@loongson.cn>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70865}
parent f4ff68af
......@@ -799,13 +799,13 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
__ Addu(sp, sp, args_count);
}
// Tail-call |function_id| if |smi_entry| == |marker|
// Tail-call |function_id| if |actual_marker| == |expected_marker|
static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm,
Register smi_entry,
OptimizationMarker marker,
Register actual_marker,
OptimizationMarker expected_marker,
Runtime::FunctionId function_id) {
Label no_match;
__ Branch(&no_match, ne, smi_entry, Operand(Smi::FromEnum(marker)));
__ Branch(&no_match, ne, actual_marker, Operand(expected_marker));
GenerateTailCallToReturnedCode(masm, function_id);
__ bind(&no_match);
}
......@@ -821,16 +821,21 @@ static void TailCallOptimizedCodeSlot(MacroAssembler* masm,
DCHECK(!AreAliased(optimized_code_entry, a1, a3, scratch1, scratch2));
Register closure = a1;
Label heal_optimized_code_slot;
// If the optimized code is cleared, go to runtime to update the optimization
// marker field.
__ LoadWeakValue(optimized_code_entry, optimized_code_entry,
&heal_optimized_code_slot);
// Check if the optimized code is marked for deopt. If it is, call the
// runtime to clear it.
Label found_deoptimized_code;
__ Lw(scratch1,
FieldMemOperand(optimized_code_entry, Code::kCodeDataContainerOffset));
__ Lw(scratch1,
FieldMemOperand(scratch1, CodeDataContainer::kKindSpecificFlagsOffset));
__ And(scratch1, scratch1, Operand(1 << Code::kMarkedForDeoptimizationBit));
__ Branch(&found_deoptimized_code, ne, scratch1, Operand(zero_reg));
__ Branch(&heal_optimized_code_slot, ne, scratch1, Operand(zero_reg));
// Optimized code is good, get it into the closure and link the closure into
// the optimized functions list, then tail call the optimized code.
......@@ -842,10 +847,11 @@ static void TailCallOptimizedCodeSlot(MacroAssembler* masm,
__ Addu(a2, optimized_code_entry, Code::kHeaderSize - kHeapObjectTag);
__ Jump(a2);
// Optimized code slot contains deoptimized code, evict it and re-enter the
// closure's code.
__ bind(&found_deoptimized_code);
GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot);
// Optimized code slot contains deoptimized code or code is cleared and
// optimized code marker isn't updated. Evict the code, update the marker
// and re-enter the closure's code.
__ bind(&heal_optimized_code_slot);
GenerateTailCallToReturnedCode(masm, Runtime::kHealOptimizedCodeSlot);
}
static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
......@@ -855,7 +861,8 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
// -- a3 : new target (preserved for callee if needed, and caller)
// -- a1 : target function (preserved for callee if needed, and caller)
// -- feedback vector (preserved for caller if needed)
// -- optimization_marker : a Smi containing a non-zero optimization marker.
// -- optimization_marker : a int32 containing a non-zero optimization
// marker.
// -----------------------------------
DCHECK(!AreAliased(feedback_vector, a1, a3, optimization_marker));
......@@ -877,7 +884,7 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
if (FLAG_debug_code) {
__ Assert(eq, AbortReason::kExpectedOptimizationSentinel,
optimization_marker,
Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)));
Operand(OptimizationMarker::kInOptimizationQueue));
}
}
......@@ -1005,18 +1012,17 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ lhu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
__ Branch(&push_stack_frame, ne, t0, Operand(FEEDBACK_VECTOR_TYPE));
// Read off the optimized code slot in the feedback vector, and if there
// Read off the optimization state in the feedback vector, and if there
// is optimized code or an optimization marker, call that instead.
Register optimized_code_entry = t0;
__ Lw(optimized_code_entry,
FieldMemOperand(feedback_vector,
FeedbackVector::kOptimizedCodeWeakOrSmiOffset));
Register optimization_state = t0;
__ Lw(optimization_state,
FieldMemOperand(feedback_vector, FeedbackVector::kFlagsOffset));
// Check if the optimized code slot is not empty.
Label optimized_code_slot_not_empty;
// Check if the optimized code slot is not empty or has a optimization marker.
Label has_optimized_code_or_marker;
__ Branch(&optimized_code_slot_not_empty, ne, optimized_code_entry,
Operand(Smi::FromEnum(OptimizationMarker::kNone)));
__ Branch(&has_optimized_code_or_marker, ne, optimization_state,
Operand(FeedbackVector::kHasNoOptimizedCodeOrMarkerValue));
Label not_optimized;
__ bind(&not_optimized);
......@@ -1162,19 +1168,25 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ jmp(&after_stack_check_interrupt);
__ bind(&optimized_code_slot_not_empty);
__ bind(&has_optimized_code_or_marker);
Label maybe_has_optimized_code;
// Check if optimized code marker is actually a weak reference to the
// optimized code as opposed to an optimization marker.
__ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code);
MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry);
// Check if optimized code marker is available
__ andi(t1, optimization_state,
FeedbackVector::OptimizationTierBits::kMask);
__ Branch(&maybe_has_optimized_code, ne, t1, Operand(zero_reg));
Register optimization_marker = optimization_state;
__ DecodeField<FeedbackVector::OptimizationMarkerBits>(optimization_marker);
MaybeOptimizeCode(masm, feedback_vector, optimization_marker);
// Fall through if there's no runnable optimized code.
__ jmp(&not_optimized);
__ bind(&maybe_has_optimized_code);
// Load code entry from the weak reference, if it was cleared, resume
// execution of unoptimized code.
__ LoadWeakValue(optimized_code_entry, optimized_code_entry, &not_optimized);
Register optimized_code_entry = optimization_state;
__ Lw(optimization_marker,
FieldMemOperand(feedback_vector,
FeedbackVector::kMaybeOptimizedCodeOffset));
TailCallOptimizedCodeSlot(masm, optimized_code_entry, t1, t3);
__ bind(&compile_lazy);
......
......@@ -816,13 +816,13 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
__ Daddu(sp, sp, args_count);
}
// Tail-call |function_id| if |smi_entry| == |marker|
// Tail-call |function_id| if |actual_marker| == |expected_marker|
static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm,
Register smi_entry,
OptimizationMarker marker,
Register actual_marker,
OptimizationMarker expected_marker,
Runtime::FunctionId function_id) {
Label no_match;
__ Branch(&no_match, ne, smi_entry, Operand(Smi::FromEnum(marker)));
__ Branch(&no_match, ne, actual_marker, Operand(expected_marker));
GenerateTailCallToReturnedCode(masm, function_id);
__ bind(&no_match);
}
......@@ -838,15 +838,20 @@ static void TailCallOptimizedCodeSlot(MacroAssembler* masm,
DCHECK(!AreAliased(optimized_code_entry, a1, a3, scratch1, scratch2));
Register closure = a1;
Label heal_optimized_code_slot;
// If the optimized code is cleared, go to runtime to update the optimization
// marker field.
__ LoadWeakValue(optimized_code_entry, optimized_code_entry,
&heal_optimized_code_slot);
// Check if the optimized code is marked for deopt. If it is, call the
// runtime to clear it.
Label found_deoptimized_code;
__ Ld(a5,
FieldMemOperand(optimized_code_entry, Code::kCodeDataContainerOffset));
__ Lw(a5, FieldMemOperand(a5, CodeDataContainer::kKindSpecificFlagsOffset));
__ And(a5, a5, Operand(1 << Code::kMarkedForDeoptimizationBit));
__ Branch(&found_deoptimized_code, ne, a5, Operand(zero_reg));
__ Branch(&heal_optimized_code_slot, ne, a5, Operand(zero_reg));
// Optimized code is good, get it into the closure and link the closure into
// the optimized functions list, then tail call the optimized code.
......@@ -860,10 +865,11 @@ static void TailCallOptimizedCodeSlot(MacroAssembler* masm,
Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(a2);
// Optimized code slot contains deoptimized code, evict it and re-enter the
// closure's code.
__ bind(&found_deoptimized_code);
GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot);
// Optimized code slot contains deoptimized code or code is cleared and
// optimized code marker isn't updated. Evict the code, update the marker
// and re-enter the closure's code.
__ bind(&heal_optimized_code_slot);
GenerateTailCallToReturnedCode(masm, Runtime::kHealOptimizedCodeSlot);
}
static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
......@@ -873,7 +879,8 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
// -- a3 : new target (preserved for callee if needed, and caller)
// -- a1 : target function (preserved for callee if needed, and caller)
// -- feedback vector (preserved for caller if needed)
// -- optimization_marker : a Smi containing a non-zero optimization marker.
// -- optimization_marker : a int32 containing a non-zero optimization
// marker.
// -----------------------------------
DCHECK(!AreAliased(feedback_vector, a1, a3, optimization_marker));
......@@ -895,7 +902,7 @@ static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector,
if (FLAG_debug_code) {
__ Assert(eq, AbortReason::kExpectedOptimizationSentinel,
optimization_marker,
Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)));
Operand(OptimizationMarker::kInOptimizationQueue));
}
}
......@@ -1023,18 +1030,17 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Lhu(a4, FieldMemOperand(a4, Map::kInstanceTypeOffset));
__ Branch(&push_stack_frame, ne, a4, Operand(FEEDBACK_VECTOR_TYPE));
// Read off the optimized code slot in the feedback vector, and if there
// Read off the optimization state in the feedback vector, and if there
// is optimized code or an optimization marker, call that instead.
Register optimized_code_entry = a4;
__ Ld(optimized_code_entry,
FieldMemOperand(feedback_vector,
FeedbackVector::kOptimizedCodeWeakOrSmiOffset));
Register optimization_state = a4;
__ Ld(optimization_state,
FieldMemOperand(feedback_vector, FeedbackVector::kFlagsOffset));
// Check if the optimized code slot is not empty.
Label optimized_code_slot_not_empty;
// Check if the optimized code slot is not empty or has a optimization marker.
Label has_optimized_code_or_marker;
__ Branch(&optimized_code_slot_not_empty, ne, optimized_code_entry,
Operand(Smi::FromEnum(OptimizationMarker::kNone)));
__ Branch(&has_optimized_code_or_marker, ne, optimization_state,
Operand(FeedbackVector::kHasNoOptimizedCodeOrMarkerValue));
Label not_optimized;
__ bind(&not_optimized);
......@@ -1181,19 +1187,25 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ jmp(&after_stack_check_interrupt);
__ bind(&optimized_code_slot_not_empty);
__ bind(&has_optimized_code_or_marker);
Label maybe_has_optimized_code;
// Check if optimized code marker is actually a weak reference to the
// optimized code as opposed to an optimization marker.
__ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code);
MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry);
// Check if optimized code marker is available
__ andi(t0, optimization_state,
FeedbackVector::OptimizationTierBits::kMask);
__ Branch(&maybe_has_optimized_code, ne, t0, Operand(zero_reg));
Register optimization_marker = optimization_state;
__ DecodeField<FeedbackVector::OptimizationMarkerBits>(optimization_marker);
MaybeOptimizeCode(masm, feedback_vector, optimization_marker);
// Fall through if there's no runnable optimized code.
__ jmp(&not_optimized);
__ bind(&maybe_has_optimized_code);
// Load code entry from the weak reference, if it was cleared, resume
// execution of unoptimized code.
__ LoadWeakValue(optimized_code_entry, optimized_code_entry, &not_optimized);
Register optimized_code_entry = optimization_state;
__ Ld(optimization_marker,
FieldMemOperand(feedback_vector,
FeedbackVector::kMaybeOptimizedCodeOffset));
TailCallOptimizedCodeSlot(masm, optimized_code_entry, t3, a5);
__ bind(&compile_lazy);
......
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