Index: src/frames.cc |
diff --git a/src/frames.cc b/src/frames.cc |
index c4653c61e29f03ba0055841d99b0c862fca280ba..481369de8a1bc6f740d81aba091e037b2364906a 100644 |
--- a/src/frames.cc |
+++ b/src/frames.cc |
@@ -214,9 +214,9 @@ SafeStackFrameIterator::SafeStackFrameIterator( |
// we check only that kMarkerOffset is within the stack bounds and do |
// compile time check that kContextOffset slot is pushed on the stack before |
// kMarkerOffset. |
- STATIC_ASSERT(StandardFrameConstants::kMarkerOffset < |
+ STATIC_ASSERT(StandardFrameConstants::kFunctionOffset < |
StandardFrameConstants::kContextOffset); |
- Address frame_marker = fp + StandardFrameConstants::kMarkerOffset; |
+ Address frame_marker = fp + StandardFrameConstants::kFunctionOffset; |
if (IsValidStackAddress(frame_marker)) { |
type = StackFrame::ComputeType(this, &state); |
top_frame_type_ = type; |
@@ -417,6 +417,8 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
State* state) { |
DCHECK(state->fp != NULL); |
+ Object* marker = Memory::Object_at( |
+ state->fp + CommonFrameConstants::kContextOrFrameTypeOffset); |
if (!iterator->can_access_heap_objects_) { |
// TODO(titzer): "can_access_heap_objects" is kind of bogus. It really |
// means that we are being called from the profiler, which can interrupt |
@@ -429,69 +431,73 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
MSAN_MEMORY_IS_INITIALIZED( |
state->fp + StandardFrameConstants::kMarkerOffset, kPointerSize); |
#endif |
- if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
- // An adapter frame has a special SMI constant for the context and |
- // is not distinguished through the marker. |
- return ARGUMENTS_ADAPTOR; |
+ Object* maybe_function = |
+ Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset); |
+ if (!marker->IsSmi()) { |
+ if (maybe_function->IsSmi()) { |
+ return NONE; |
+ } else if (FLAG_ignition && IsInterpreterFramePc(iterator->isolate(), |
+ *(state->pc_address))) { |
+ return INTERPRETED; |
+ } else { |
+ return JAVA_SCRIPT; |
+ } |
} |
- Object* marker = |
- Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
- if (marker->IsSmi()) { |
- return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
- } else if (FLAG_ignition && IsInterpreterFramePc(iterator->isolate(), |
- *(state->pc_address))) { |
- return INTERPRETED; |
+ } else { |
+ // Look up the code object to figure out the type of the stack frame. |
+ Code* code_obj = |
+ GetContainingCode(iterator->isolate(), *(state->pc_address)); |
+ if (code_obj != nullptr) { |
+ if (code_obj->is_interpreter_entry_trampoline() || |
+ code_obj->is_interpreter_enter_bytecode_dispatch()) { |
+ return INTERPRETED; |
+ } |
+ switch (code_obj->kind()) { |
+ case Code::FUNCTION: |
+ return JAVA_SCRIPT; |
+ case Code::OPTIMIZED_FUNCTION: |
+ return OPTIMIZED; |
+ case Code::WASM_FUNCTION: |
+ return WASM; |
+ case Code::WASM_TO_JS_FUNCTION: |
+ return WASM_TO_JS; |
+ case Code::JS_TO_WASM_FUNCTION: |
+ return JS_TO_WASM; |
+ default: |
+ // All other types should have an explicit marker |
+ break; |
+ } |
} else { |
- return JAVA_SCRIPT; |
+ return NONE; |
} |
} |
- // Look up the code object to figure out the type of the stack frame. |
- Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address)); |
- |
- Object* marker = |
- Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
- if (code_obj != nullptr) { |
- switch (code_obj->kind()) { |
- case Code::FUNCTION: |
- return JAVA_SCRIPT; |
- case Code::OPTIMIZED_FUNCTION: |
- return OPTIMIZED; |
- case Code::WASM_FUNCTION: |
- return WASM; |
- case Code::WASM_TO_JS_FUNCTION: |
- return WASM_TO_JS; |
- case Code::JS_TO_WASM_FUNCTION: |
- return JS_TO_WASM; |
- case Code::BUILTIN: |
- if (!marker->IsSmi()) { |
- if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
- // An adapter frame has a special SMI constant for the context and |
- // is not distinguished through the marker. |
- return ARGUMENTS_ADAPTOR; |
- } else { |
- // The interpreter entry trampoline has a non-SMI marker. |
- DCHECK(code_obj->is_interpreter_entry_trampoline() || |
- code_obj->is_interpreter_enter_bytecode_dispatch()); |
- return INTERPRETED; |
- } |
- } |
- break; // Marker encodes the frame type. |
- case Code::HANDLER: |
- if (!marker->IsSmi()) { |
- // Only hydrogen code stub handlers can have a non-SMI marker. |
- DCHECK(code_obj->is_hydrogen_stub()); |
- return OPTIMIZED; |
- } |
- break; // Marker encodes the frame type. |
- default: |
- break; // Marker encodes the frame type. |
- } |
+ DCHECK(marker->IsSmi()); |
+ StackFrame::Type candidate = |
+ static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
+ switch (candidate) { |
+ case ENTRY: |
+ case ENTRY_CONSTRUCT: |
+ case EXIT: |
+ case STUB: |
+ case STUB_FAILURE_TRAMPOLINE: |
+ case INTERNAL: |
+ case CONSTRUCT: |
+ case ARGUMENTS_ADAPTOR: |
+ return candidate; |
+ case JS_TO_WASM: |
+ case WASM_TO_JS: |
+ case WASM: |
+ case JAVA_SCRIPT: |
+ case OPTIMIZED: |
+ case INTERPRETED: |
+ default: |
+ // Unoptimized and optimized JavaScript frames, including |
+ // interpreted frames, should never have a StackFrame::Type |
+ // marker. If we find one, we're likely being called from the |
+ // profiler in a bogus stack frame. |
+ return NONE; |
} |
- |
- // Didn't find a code object, or the code kind wasn't specific enough. |
- // The marker should encode the frame type. |
- return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
} |
@@ -579,7 +585,7 @@ void ExitFrame::Iterate(ObjectVisitor* v) const { |
Address ExitFrame::GetCallerStackPointer() const { |
- return fp() + ExitFrameConstants::kCallerSPDisplacement; |
+ return fp() + ExitFrameConstants::kCallerSPOffset; |
} |
@@ -655,13 +661,49 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { |
SafepointEntry safepoint_entry; |
Code* code = StackFrame::GetSafepointData( |
isolate(), pc(), &safepoint_entry, &stack_slots); |
- unsigned slot_space = |
- stack_slots * kPointerSize - StandardFrameConstants::kFixedFrameSize; |
+ unsigned slot_space = stack_slots * kPointerSize; |
+ |
+ // Determine the fixed header and spill slot area size. |
+ int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp; |
+ Object* marker = Memory::Object_at(fp() - kPointerSize); |
+ if (marker->IsSmi()) { |
+ StackFrame::Type candidate = |
+ static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
+ switch (candidate) { |
+ case ENTRY: |
+ case ENTRY_CONSTRUCT: |
+ case EXIT: |
+ case STUB_FAILURE_TRAMPOLINE: |
+ case ARGUMENTS_ADAPTOR: |
+ case STUB: |
+ case INTERNAL: |
+ case CONSTRUCT: |
+ case JS_TO_WASM: |
+ case WASM_TO_JS: |
+ case WASM: |
+ frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp; |
+ break; |
+ case JAVA_SCRIPT: |
+ case OPTIMIZED: |
+ case INTERPRETED: |
+ // These frame types have a context, but they are actually stored |
+ // in the place on the stack that one finds the frame type. |
+ UNREACHABLE(); |
+ break; |
+ case NONE: |
+ case NUMBER_OF_TYPES: |
+ case MANUAL: |
+ UNREACHABLE(); |
+ break; |
+ } |
+ } |
+ slot_space -= |
+ (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp); |
- // Visit the outgoing parameters. |
+ Object** frame_header_base = &Memory::Object_at(fp() - frame_header_size); |
+ Object** frame_header_limit = &Memory::Object_at(fp()); |
Object** parameters_base = &Memory::Object_at(sp()); |
- Object** parameters_limit = &Memory::Object_at( |
- fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); |
+ Object** parameters_limit = frame_header_base - slot_space / kPointerSize; |
// Visit the parameters that may be on top of the saved registers. |
if (safepoint_entry.argument_count() > 0) { |
@@ -714,10 +756,7 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { |
if (!is_wasm() && !is_wasm_to_js()) { |
// Visit the context in stub frame and JavaScript frame. |
// Visit the function in JavaScript frame. |
- Object** fixed_base = |
- &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); |
- Object** fixed_limit = &Memory::Object_at(fp()); |
- v->VisitPointers(fixed_base, fixed_limit); |
+ v->VisitPointers(frame_header_base, frame_header_limit); |
} |
} |
@@ -733,7 +772,7 @@ Code* StubFrame::unchecked_code() const { |
Address StubFrame::GetCallerStackPointer() const { |
- return fp() + ExitFrameConstants::kCallerSPDisplacement; |
+ return fp() + ExitFrameConstants::kCallerSPOffset; |
} |
@@ -1241,7 +1280,7 @@ Code* WasmFrame::unchecked_code() const { |
void WasmFrame::Iterate(ObjectVisitor* v) const { IterateCompiledFrame(v); } |
Address WasmFrame::GetCallerStackPointer() const { |
- return fp() + ExitFrameConstants::kCallerSPDisplacement; |
+ return fp() + ExitFrameConstants::kCallerSPOffset; |
} |
namespace { |
@@ -1458,10 +1497,10 @@ void InternalFrame::Iterate(ObjectVisitor* v) const { |
void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { |
Object** base = &Memory::Object_at(sp()); |
- Object** limit = &Memory::Object_at(fp() + |
- kFirstRegisterParameterFrameOffset); |
+ Object** limit = &Memory::Object_at( |
+ fp() + StubFailureTrampolineFrameConstants::kFixedHeaderBottomOffset); |
v->VisitPointers(base, limit); |
- base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); |
+ base = &Memory::Object_at(fp() + StandardFrameConstants::kFunctionOffset); |
const int offset = StandardFrameConstants::kLastObjectOffset; |
limit = &Memory::Object_at(fp() + offset) + 1; |
v->VisitPointers(base, limit); |