Commit a9915587 authored by jgruber's avatar jgruber Committed by Commit bot

[builtins] Show builtin frames in PrintStack()

Builtin frames can simply use the existing JavaScriptFrame::Print
method. Builtin exit frames need their own implementation which can print
the function name, receiver and parameters.

R=bmeurer@chromium.org, yangguo@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2134093002
Cr-Commit-Position: refs/heads/master@{#37644}
parent 41b88257
......@@ -101,22 +101,13 @@ inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
inline BuiltinExitFrame::BuiltinExitFrame(StackFrameIteratorBase* iterator)
: ExitFrame(iterator) {}
inline Object* BuiltinExitFrame::target_slot_object() const {
return Memory::Object_at(fp() + BuiltinExitFrameConstants::kTargetOffset);
}
inline Object* BuiltinExitFrame::new_target_slot_object() const {
return Memory::Object_at(fp() + BuiltinExitFrameConstants::kNewTargetOffset);
}
inline Object* BuiltinExitFrame::receiver_slot_object() const {
// The receiver is the first argument on the frame.
// fp[1]: return address.
// fp[2]: the last argument (new target).
// fp[4]: argc.
// fp[2 + argc - 1]: receiver.
Object* argc_slot =
Memory::Object_at(fp() + BuiltinExitFrameConstants::kArgcOffset);
Object* argc_slot = argc_slot_object();
DCHECK(argc_slot->IsSmi());
int argc = Smi::cast(argc_slot)->value();
......@@ -125,6 +116,18 @@ inline Object* BuiltinExitFrame::receiver_slot_object() const {
return Memory::Object_at(fp() + receiverOffset);
}
inline Object* BuiltinExitFrame::argc_slot_object() const {
return Memory::Object_at(fp() + BuiltinExitFrameConstants::kArgcOffset);
}
inline Object* BuiltinExitFrame::target_slot_object() const {
return Memory::Object_at(fp() + BuiltinExitFrameConstants::kTargetOffset);
}
inline Object* BuiltinExitFrame::new_target_slot_object() const {
return Memory::Object_at(fp() + BuiltinExitFrameConstants::kNewTargetOffset);
}
inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
: StackFrame(iterator) {
}
......
......@@ -657,6 +657,46 @@ bool BuiltinExitFrame::IsConstructor() const {
return !new_target_slot_object()->IsUndefined(isolate());
}
Object* BuiltinExitFrame::GetParameter(int i) const {
DCHECK(i >= 0 && i < ComputeParametersCount());
int offset = BuiltinExitFrameConstants::kArgcOffset + (i + 1) * kPointerSize;
return Memory::Object_at(fp() + offset);
}
int BuiltinExitFrame::ComputeParametersCount() const {
Object* argc_slot = argc_slot_object();
DCHECK(argc_slot->IsSmi());
// Argc also counts the receiver, target, new target, and argc itself as args,
// therefore the real argument count is argc - 4.
int argc = Smi::cast(argc_slot)->value() - 4;
DCHECK(argc >= 0);
return argc;
}
void BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
int index) const {
DisallowHeapAllocation no_gc;
Object* receiver = this->receiver();
JSFunction* function = this->function();
accumulator->PrintSecurityTokenIfChanged(function);
PrintIndex(accumulator, mode, index);
accumulator->Add("builtin exit frame: ");
Code* code = NULL;
if (IsConstructor()) accumulator->Add("new ");
accumulator->PrintFunction(function, receiver, &code);
accumulator->Add("(this=%o", receiver);
// Print the parameters.
int parameters_count = ComputeParametersCount();
for (int i = 0; i < parameters_count; i++) {
accumulator->Add(",%o", GetParameter(i));
}
accumulator->Add(")\n\n");
}
Address StandardFrame::GetExpressionAddress(int n) const {
const int offset = StandardFrameConstants::kExpressionsOffset;
return fp() + offset - n * kPointerSize;
......@@ -1377,15 +1417,14 @@ Code* ArgumentsAdaptorFrame::unchecked_code() const {
Builtins::kArgumentsAdaptorTrampoline);
}
void BuiltinFrame::Print(StringStream* accumulator, PrintMode mode,
int index) const {
// TODO(bmeurer)
}
int BuiltinFrame::GetNumberOfIncomingArguments() const {
return Smi::cast(GetExpression(0))->value();
}
void BuiltinFrame::PrintFrameKind(StringStream* accumulator) const {
accumulator->Add("builtin frame: ");
}
Address InternalFrame::GetCallerStackPointer() const {
// Internal frames have no arguments. The stack pointer of the
// caller is at a fixed offset from the frame pointer.
......@@ -1466,6 +1505,7 @@ void JavaScriptFrame::Print(StringStream* accumulator,
accumulator->PrintSecurityTokenIfChanged(function);
PrintIndex(accumulator, mode, index);
PrintFrameKind(accumulator);
Code* code = NULL;
if (IsConstructor()) accumulator->Add("new ");
accumulator->PrintFunction(function, receiver, &code);
......
......@@ -670,13 +670,20 @@ class BuiltinExitFrame : public ExitFrame {
bool IsConstructor() const;
void Print(StringStream* accumulator, PrintMode mode,
int index) const override;
protected:
inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
private:
Object* GetParameter(int i) const;
int ComputeParametersCount() const;
inline Object* receiver_slot_object() const;
inline Object* argc_slot_object() const;
inline Object* target_slot_object() const;
inline Object* new_target_slot_object() const;
inline Object* receiver_slot_object() const;
friend class StackFrameIteratorBase;
};
......@@ -878,6 +885,8 @@ class JavaScriptFrame : public StandardFrame {
// receiver, and any callee-saved registers.
void IterateArguments(ObjectVisitor* v) const;
virtual void PrintFrameKind(StringStream* accumulator) const {}
private:
inline Object* function_slot_object() const;
......@@ -1022,13 +1031,11 @@ class BuiltinFrame final : public JavaScriptFrame {
return static_cast<BuiltinFrame*>(frame);
}
// Printing support.
void Print(StringStream* accumulator, PrintMode mode, int index) const final;
protected:
inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
int GetNumberOfIncomingArguments() const final;
void PrintFrameKind(StringStream* accumulator) const override;
private:
friend class StackFrameIteratorBase;
......
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