Index: src/frames.cc |
diff --git a/src/frames.cc b/src/frames.cc |
index 20776f6b1b37613ecfc1637b737677b500ccebe7..86aea896695c3475a9356f1b3b2fc3cad055ad4b 100644 |
--- a/src/frames.cc |
+++ b/src/frames.cc |
@@ -181,8 +181,8 @@ bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const { |
return (script->IsScript() && |
Script::TYPE_NATIVE != Script::cast(script)->type()); |
} |
- // apart from javascript, only wasm is valid |
- return frame->is_wasm(); |
+ // apart from javascript, only wasm and builtin_exit are valid |
+ return frame->is_wasm() || frame->is_builtin_exit(); |
} |
@@ -324,7 +324,7 @@ void SafeStackFrameIterator::Advance() { |
external_callback_scope_ = external_callback_scope_->previous(); |
} |
if (frame_->is_java_script()) break; |
- if (frame_->is_exit()) { |
+ if (frame_->is_exit() || frame_->is_builtin_exit()) { |
// Some of the EXIT frames may have ExternalCallbackScope allocated on |
// top of them. In that case the scope corresponds to the first EXIT |
// frame beneath it. There may be other EXIT frames on top of the |
@@ -488,6 +488,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
case ENTRY: |
case ENTRY_CONSTRUCT: |
case EXIT: |
+ case BUILTIN_EXIT: |
case STUB: |
case STUB_FAILURE_TRAMPOLINE: |
case INTERNAL: |
@@ -561,7 +562,6 @@ Object*& ExitFrame::code_slot() const { |
return Memory::Object_at(fp() + offset); |
} |
- |
Code* ExitFrame::unchecked_code() const { |
return reinterpret_cast<Code*>(code_slot()); |
} |
@@ -603,6 +603,26 @@ StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
Address sp = ComputeStackPointer(fp); |
FillState(fp, sp, state); |
DCHECK(*state->pc_address != NULL); |
+ |
+ return ComputeFrameType(fp); |
+} |
+ |
+StackFrame::Type ExitFrame::ComputeFrameType(Address fp) { |
+ // Distinguish between between regular and builtin exit frames. |
+ // Default to EXIT in all hairy cases (e.g., when called from profiler). |
+ const int offset = CommonFrameConstants::kContextOrFrameTypeOffset; |
+ Object* marker = Memory::Object_at(fp + offset); |
+ |
+ if (!marker->IsSmi()) { |
+ return EXIT; |
+ } |
+ |
+ StackFrame::Type frame_type = |
+ static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
+ if (frame_type == EXIT || frame_type == BUILTIN_EXIT) { |
+ return frame_type; |
+ } |
+ |
return EXIT; |
} |
@@ -625,6 +645,10 @@ void ExitFrame::FillState(Address fp, Address sp, State* state) { |
state->constant_pool_address = NULL; |
} |
+JSFunction* BuiltinExitFrame::function() const { |
+ return JSFunction::cast(function_slot_object()); |
+} |
+ |
Address StandardFrame::GetExpressionAddress(int n) const { |
const int offset = StandardFrameConstants::kExpressionsOffset; |
return fp() + offset - n * kPointerSize; |
@@ -683,6 +707,7 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { |
case ENTRY: |
case ENTRY_CONSTRUCT: |
case EXIT: |
+ case BUILTIN_EXIT: |
case STUB_FAILURE_TRAMPOLINE: |
case ARGUMENTS_ADAPTOR: |
case STUB: |