Chromium Code Reviews| Index: src/frames.cc |
| diff --git a/src/frames.cc b/src/frames.cc |
| index c4653c61e29f03ba0055841d99b0c862fca280ba..0157a3a4f39a3062560a18ccf31d4e1c0e5c188d 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,36 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
| State* state) { |
| DCHECK(state->fp != NULL); |
| + Object* marker = Memory::Object_at( |
| + state->fp + CommonFrameConstants::kContextOrFrameTypeOffset); |
| + 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: |
| + case STUB_FAILURE_TRAMPOLINE: |
| + case INTERNAL: |
| + case CONSTRUCT: |
| + case ARGUMENTS_ADAPTOR: |
| + case WASM_TO_JS: |
|
titzer
2016/03/07 10:48:43
As discussed offline, if these two frame types don
danno
2016/03/08 07:04:44
Done.
|
| + case WASM: |
| + return candidate; |
| + 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; |
| + } |
| + } |
| + |
| + Object* maybe_function = |
| + Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset); |
| 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,15 +459,8 @@ 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* marker = |
| - Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
| - if (marker->IsSmi()) { |
| - return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
| + if (maybe_function->IsSmi()) { |
| + return NONE; |
| } else if (FLAG_ignition && IsInterpreterFramePc(iterator->isolate(), |
| *(state->pc_address))) { |
| return INTERPRETED; |
| @@ -448,50 +471,27 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
| // 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::OPTIMIZED_FUNCTION: |
| + return OPTIMIZED; |
| 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. |
| + DCHECK(!maybe_function->IsSmi()); |
| + DCHECK(code_obj->is_interpreter_entry_trampoline() || |
| + code_obj->is_interpreter_enter_bytecode_dispatch()); |
| + return INTERPRETED; |
| default: |
| - break; // Marker encodes the frame type. |
| + // All other types should have an explicit marker |
| + UNREACHABLE(); |
| + break; |
| } |
| } |
| - // 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()); |
| + return NONE; |
| } |
| @@ -579,7 +579,7 @@ void ExitFrame::Iterate(ObjectVisitor* v) const { |
| Address ExitFrame::GetCallerStackPointer() const { |
| - return fp() + ExitFrameConstants::kCallerSPDisplacement; |
| + return fp() + ExitFrameConstants::kCallerSPOffset; |
| } |
| @@ -655,13 +655,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 +750,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 +766,7 @@ Code* StubFrame::unchecked_code() const { |
| Address StubFrame::GetCallerStackPointer() const { |
| - return fp() + ExitFrameConstants::kCallerSPDisplacement; |
| + return fp() + ExitFrameConstants::kCallerSPOffset; |
| } |
| @@ -1241,7 +1274,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 +1491,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); |