Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1219)

Unified Diff: src/builtins/ppc/builtins-ppc.cc

Issue 2947903002: PPC/s390: [compiler] Drive optimizations with feedback vector (reland) (Closed)
Patch Set: fix ppc issue Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/builtins/s390/builtins-s390.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/ppc/builtins-ppc.cc
diff --git a/src/builtins/ppc/builtins-ppc.cc b/src/builtins/ppc/builtins-ppc.cc
index 35713097dd00cd0eafd8a4a6e0e86e666bf1f539..f805818c8186d4d901b0b774c958f5a6ba50c7ac 100644
--- a/src/builtins/ppc/builtins-ppc.cc
+++ b/src/builtins/ppc/builtins-ppc.cc
@@ -427,23 +427,6 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
__ JumpToJSEntry(ip);
}
-void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
- // Checking whether the queued function is ready for install is optional,
- // since we come across interrupts and stack checks elsewhere. However,
- // not checking may delay installing ready functions, and always checking
- // would be quite expensive. A good compromise is to first check against
- // stack limit as a cue for an interrupt signal.
- Label ok;
- __ LoadRoot(ip, Heap::kStackLimitRootIndex);
- __ cmpl(sp, ip);
- __ bge(&ok);
-
- GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
-
- __ bind(&ok);
- GenerateTailCallToSharedCode(masm);
-}
-
namespace {
void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
@@ -1033,6 +1016,120 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
__ add(sp, sp, args_count);
}
+// Tail-call |function_id| if |smi_entry| == |marker|
+static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm,
+ Register smi_entry,
+ OptimizationMarker marker,
+ Runtime::FunctionId function_id) {
+ Label no_match;
+ __ CmpSmiLiteral(smi_entry, Smi::FromEnum(marker), r0);
+ __ bne(&no_match);
+ GenerateTailCallToReturnedCode(masm, function_id);
+ __ bind(&no_match);
+}
+
+static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm,
+ Register feedback_vector,
+ Register scratch1, Register scratch2,
+ Register scratch3) {
+ // ----------- S t a t e -------------
+ // -- r0 : argument count (preserved for callee if needed, and caller)
+ // -- r3 : new target (preserved for callee if needed, and caller)
+ // -- r1 : target function (preserved for callee if needed, and caller)
+ // -- feedback vector (preserved for caller if needed)
+ // -----------------------------------
+ DCHECK(
+ !AreAliased(feedback_vector, r3, r4, r6, scratch1, scratch2, scratch3));
+
+ Label optimized_code_slot_is_cell, fallthrough;
+
+ Register closure = r4;
+ Register optimized_code_entry = scratch1;
+
+ const int kOptimizedCodeCellOffset =
+ FeedbackVector::kOptimizedCodeIndex * kPointerSize +
+ FeedbackVector::kHeaderSize;
+ __ LoadP(optimized_code_entry,
+ FieldMemOperand(feedback_vector, kOptimizedCodeCellOffset));
+
+ // Check if the code entry is a Smi. If yes, we interpret it as an
+ // optimisation marker. Otherwise, interpret is as a weak cell to a code
+ // object.
+ __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_cell);
+
+ {
+ // Optimized code slot is a Smi optimization marker.
+
+ // Fall through if no optimization trigger.
+ __ CmpSmiLiteral(optimized_code_entry,
+ Smi::FromEnum(OptimizationMarker::kNone), r0);
+ __ beq(&fallthrough);
+
+ TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry,
+ OptimizationMarker::kCompileOptimized,
+ Runtime::kCompileOptimized_NotConcurrent);
+ TailCallRuntimeIfMarkerEquals(
+ masm, optimized_code_entry,
+ OptimizationMarker::kCompileOptimizedConcurrent,
+ Runtime::kCompileOptimized_Concurrent);
+
+ {
+ // Otherwise, the marker is InOptimizationQueue.
+ if (FLAG_debug_code) {
+ __ CmpSmiLiteral(
+ optimized_code_entry,
+ Smi::FromEnum(OptimizationMarker::kInOptimizationQueue), r0);
+ __ Assert(eq, kExpectedOptimizationSentinel);
+ }
+
+ // Checking whether the queued function is ready for install is optional,
+ // since we come across interrupts and stack checks elsewhere. However,
+ // not checking may delay installing ready functions, and always checking
+ // would be quite expensive. A good compromise is to first check against
+ // stack limit as a cue for an interrupt signal.
+ __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+ __ cmpl(sp, ip);
+ __ bge(&fallthrough);
+ GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
+ }
+ }
+
+ {
+ // Optimized code slot is a WeakCell.
+ __ bind(&optimized_code_slot_is_cell);
+
+ __ LoadP(optimized_code_entry,
+ FieldMemOperand(optimized_code_entry, WeakCell::kValueOffset));
+ __ JumpIfSmi(optimized_code_entry, &fallthrough);
+
+ // Check if the optimized code is marked for deopt. If it is, call the
+ // runtime to clear it.
+ Label found_deoptimized_code;
+ __ LoadP(scratch2, FieldMemOperand(optimized_code_entry,
+ Code::kKindSpecificFlags1Offset));
+ __ TestBit(scratch2, Code::kMarkedForDeoptimizationBit, r0);
+ __ bne(&found_deoptimized_code, cr0);
+
+ // Optimized code is good, get it into the closure and link the closure into
+ // the optimized functions list, then tail call the optimized code.
+ // The feedback vector is no longer used, so re-use it as a scratch
+ // register.
+ ReplaceClosureEntryWithOptimizedCode(masm, optimized_code_entry, closure,
+ scratch2, scratch3, feedback_vector);
+ __ mr(ip, optimized_code_entry);
+ __ Jump(optimized_code_entry);
+
+ // Optimized code slot contains deoptimized code, evict it and re-enter the
+ // closure's code.
+ __ bind(&found_deoptimized_code);
+ GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot);
+ }
+
+ // Fall-through if the optimized code cell is clear and there is no
+ // optimization marker.
+ __ bind(&fallthrough);
+}
+
// Generate code for entering a JS function with the interpreter.
// On entry to the function the receiver and arguments have been pushed on the
// stack left to right. The actual argument count matches the formal parameter
@@ -1052,36 +1149,33 @@ static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
ProfileEntryHookStub::MaybeCallEntryHook(masm);
+ Register closure = r4;
+ Register feedback_vector = r5;
+
+ // Load the feedback vector from the closure.
+ __ LoadP(feedback_vector,
+ FieldMemOperand(closure, JSFunction::kFeedbackVectorOffset));
+ __ LoadP(feedback_vector,
+ FieldMemOperand(feedback_vector, Cell::kValueOffset));
+ // Read off the optimized code slot in the feedback vector, and if there
+ // is optimized code or an optimization marker, call that instead.
+ MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r7, r9, r8);
+
// Open a frame scope to indicate that there is a frame on the stack. The
// MANUAL indicates that the scope shouldn't actually generate code to set up
// the frame (that is done below).
FrameScope frame_scope(masm, StackFrame::MANUAL);
- __ PushStandardFrame(r4);
-
- // First check if there is optimized code in the feedback vector which we
- // could call instead.
- Label switch_to_optimized_code;
-
- Register optimized_code_entry = r7;
- __ LoadP(r3, FieldMemOperand(r4, JSFunction::kFeedbackVectorOffset));
- __ LoadP(r3, FieldMemOperand(r3, Cell::kValueOffset));
- __ LoadP(
- optimized_code_entry,
- FieldMemOperand(r3, FeedbackVector::kOptimizedCodeIndex * kPointerSize +
- FeedbackVector::kHeaderSize));
- __ LoadP(optimized_code_entry,
- FieldMemOperand(optimized_code_entry, WeakCell::kValueOffset));
- __ JumpIfNotSmi(optimized_code_entry, &switch_to_optimized_code);
+ __ PushStandardFrame(closure);
// Get the bytecode array from the function object (or from the DebugInfo if
// it is present) and load it into kInterpreterBytecodeArrayRegister.
Label maybe_load_debug_bytecode_array, bytecode_array_loaded;
- __ LoadP(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+ __ LoadP(r3, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
// Load original bytecode array or the debug copy.
__ LoadP(kInterpreterBytecodeArrayRegister,
FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset));
- __ LoadP(r5, FieldMemOperand(r3, SharedFunctionInfo::kDebugInfoOffset));
- __ TestIfSmi(r5, r0);
+ __ LoadP(r7, FieldMemOperand(r3, SharedFunctionInfo::kDebugInfoOffset));
+ __ TestIfSmi(r7, r0);
__ bne(&maybe_load_debug_bytecode_array, cr0);
__ bind(&bytecode_array_loaded);
@@ -1095,16 +1189,17 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ bne(&switch_to_different_code_kind);
// Increment invocation count for the function.
- __ LoadP(r7, FieldMemOperand(r4, JSFunction::kFeedbackVectorOffset));
- __ LoadP(r7, FieldMemOperand(r7, Cell::kValueOffset));
- __ LoadP(r8, FieldMemOperand(
- r7, FeedbackVector::kInvocationCountIndex * kPointerSize +
- FeedbackVector::kHeaderSize));
+ __ LoadP(
+ r8, FieldMemOperand(feedback_vector,
+ FeedbackVector::kInvocationCountIndex * kPointerSize +
+ FeedbackVector::kHeaderSize));
__ AddSmiLiteral(r8, r8, Smi::FromInt(1), r0);
- __ StoreP(r8, FieldMemOperand(
- r7, FeedbackVector::kInvocationCountIndex * kPointerSize +
- FeedbackVector::kHeaderSize),
- r0);
+ __ StoreP(
+ r8,
+ FieldMemOperand(feedback_vector,
+ FeedbackVector::kInvocationCountIndex * kPointerSize +
+ FeedbackVector::kHeaderSize),
+ r0);
// Check function data field is actually a BytecodeArray object.
@@ -1182,12 +1277,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
// SharedFunctionInfo::kFunctionDataOffset.
Label done;
__ bind(&maybe_load_debug_bytecode_array);
- __ LoadP(ip, FieldMemOperand(r5, DebugInfo::kFlagsOffset));
+ __ LoadP(ip, FieldMemOperand(r7, DebugInfo::kFlagsOffset));
__ SmiUntag(ip);
__ andi(r0, ip, Operand(DebugInfo::kHasBreakInfo));
__ beq(&done, cr0);
__ LoadP(kInterpreterBytecodeArrayRegister,
- FieldMemOperand(r5, DebugInfo::kDebugBytecodeArrayOffset));
+ FieldMemOperand(r7, DebugInfo::kDebugBytecodeArrayOffset));
__ bind(&done);
__ b(&bytecode_array_loaded);
@@ -1196,35 +1291,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
// closure by switching the code entry field over to the new code as well.
__ bind(&switch_to_different_code_kind);
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
- __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+ __ LoadP(r7, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kCodeOffset));
__ addi(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ StoreP(r7, FieldMemOperand(r4, JSFunction::kCodeEntryOffset), r0);
- __ RecordWriteCodeEntryField(r4, r7, r8);
+ __ StoreP(r7, FieldMemOperand(closure, JSFunction::kCodeEntryOffset), r0);
+ __ RecordWriteCodeEntryField(closure, r7, r8);
__ JumpToJSEntry(r7);
-
- // If there is optimized code on the type feedback vector, check if it is good
- // to run, and if so, self heal the closure and call the optimized code.
- __ bind(&switch_to_optimized_code);
- __ LeaveFrame(StackFrame::JAVA_SCRIPT);
- Label gotta_call_runtime;
-
- // Check if the optimized code is marked for deopt.
- __ lwz(r8, FieldMemOperand(optimized_code_entry,
- Code::kKindSpecificFlags1Offset));
- __ TestBit(r8, Code::kMarkedForDeoptimizationBit, r0);
- __ bne(&gotta_call_runtime, cr0);
-
- // Optimized code is good, get it into the closure and link the closure into
- // the optimized functions list, then tail call the optimized code.
- ReplaceClosureEntryWithOptimizedCode(masm, optimized_code_entry, r4, r9, r8,
- r5);
- __ JumpToJSEntry(optimized_code_entry);
-
- // Optimized code is marked for deopt, bailout to the CompileLazy runtime
- // function which will clear the feedback vector's optimized code slot.
- __ bind(&gotta_call_runtime);
- GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot);
}
static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
@@ -1459,6 +1531,34 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
Generate_InterpreterEnterBytecode(masm);
}
+void Builtins::Generate_CheckOptimizationMarker(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- r3 : argument count (preserved for callee)
+ // -- r6 : new target (preserved for callee)
+ // -- r4 : target function (preserved for callee)
+ // -----------------------------------
+ Register closure = r4;
+
+ // Get the feedback vector.
+ Register feedback_vector = r5;
+ __ LoadP(feedback_vector,
+ FieldMemOperand(closure, JSFunction::kFeedbackVectorOffset));
+ __ LoadP(feedback_vector,
+ FieldMemOperand(feedback_vector, Cell::kValueOffset));
+
+ // The feedback vector must be defined.
+ if (FLAG_debug_code) {
+ __ CompareRoot(feedback_vector, Heap::kUndefinedValueRootIndex);
+ __ Assert(ne, BailoutReason::kExpectedFeedbackVector);
+ }
+
+ // Is there an optimization marker or optimized code in the feedback vector?
+ MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r7, r9, r8);
+
+ // Otherwise, tail call the SFI code.
+ GenerateTailCallToSharedCode(masm);
+}
+
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
@@ -1467,42 +1567,25 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
// -----------------------------------
// First lookup code, maybe we don't need to compile!
Label gotta_call_runtime;
- Label try_shared;
Register closure = r4;
- Register index = r5;
+ Register feedback_vector = r5;
// Do we have a valid feedback vector?
- __ LoadP(index, FieldMemOperand(closure, JSFunction::kFeedbackVectorOffset));
- __ LoadP(index, FieldMemOperand(index, Cell::kValueOffset));
- __ JumpIfRoot(index, Heap::kUndefinedValueRootIndex, &gotta_call_runtime);
+ __ LoadP(feedback_vector,
+ FieldMemOperand(closure, JSFunction::kFeedbackVectorOffset));
+ __ LoadP(feedback_vector,
+ FieldMemOperand(feedback_vector, Cell::kValueOffset));
+ __ JumpIfRoot(feedback_vector, Heap::kUndefinedValueRootIndex,
+ &gotta_call_runtime);
- // Is optimized code available in the feedback vector?
- Register entry = r7;
- __ LoadP(entry, FieldMemOperand(index, FeedbackVector::kOptimizedCodeIndex *
- kPointerSize +
- FeedbackVector::kHeaderSize));
- __ LoadP(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
- __ JumpIfSmi(entry, &try_shared);
-
- // Found code, check if it is marked for deopt, if so call into runtime to
- // clear the optimized code slot.
- __ lwz(r8, FieldMemOperand(entry, Code::kKindSpecificFlags1Offset));
- __ TestBit(r8, Code::kMarkedForDeoptimizationBit, r0);
- __ bne(&gotta_call_runtime, cr0);
-
- // Code is good, get it into the closure and tail call.
- ReplaceClosureEntryWithOptimizedCode(masm, entry, closure, r9, r8, r5);
- __ JumpToJSEntry(entry);
+ // Is there an optimization marker or optimized code in the feedback vector?
+ MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r7, r9, r8);
// We found no optimized code.
- __ bind(&try_shared);
+ Register entry = r7;
__ LoadP(entry,
FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
- // Is the shared function marked for tier up?
- __ lwz(r8, FieldMemOperand(entry, SharedFunctionInfo::kCompilerHintsOffset));
- __ TestBit(r8, SharedFunctionInfo::MarkedForTierUpBit::kShift, r0);
- __ bne(&gotta_call_runtime, cr0);
// If SFI points to anything other than CompileLazy, install that.
__ LoadP(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
@@ -1520,15 +1603,6 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
-void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
- GenerateTailCallToReturnedCode(masm,
- Runtime::kCompileOptimized_NotConcurrent);
-}
-
-void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
- GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
-}
-
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
« no previous file with comments | « no previous file | src/builtins/s390/builtins-s390.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698