Commit 6d59c1b6 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Always iterate outgoing arguments as a part of caller frame.

Change caller_sp() to always point to the place after outgoing arguments.

Review URL: http://codereview.chromium.org/6720049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7504 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7ef5cec9
...@@ -148,15 +148,26 @@ inline bool StandardFrame::IsConstructFrame(Address fp) { ...@@ -148,15 +148,26 @@ inline bool StandardFrame::IsConstructFrame(Address fp) {
} }
Address JavaScriptFrame::GetParameterSlot(int index) const {
int param_count = ComputeParametersCount();
ASSERT(-1 <= index && index < param_count);
int parameter_offset = (param_count - index - 1) * kPointerSize;
return caller_sp() + parameter_offset;
}
Object* JavaScriptFrame::GetParameter(int index) const {
return Memory::Object_at(GetParameterSlot(index));
}
inline Object* JavaScriptFrame::receiver() const { inline Object* JavaScriptFrame::receiver() const {
const int offset = JavaScriptFrameConstants::kReceiverOffset; return GetParameter(-1);
return Memory::Object_at(caller_sp() + offset);
} }
inline void JavaScriptFrame::set_receiver(Object* value) { inline void JavaScriptFrame::set_receiver(Object* value) {
const int offset = JavaScriptFrameConstants::kReceiverOffset; Memory::Object_at(GetParameterSlot(-1)) = value;
Memory::Object_at(caller_sp() + offset) = value;
} }
......
...@@ -579,9 +579,7 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const { ...@@ -579,9 +579,7 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const {
isolate(), pc(), &safepoint_entry, &stack_slots); isolate(), pc(), &safepoint_entry, &stack_slots);
unsigned slot_space = stack_slots * kPointerSize; unsigned slot_space = stack_slots * kPointerSize;
// Visit the outgoing parameters. This is usually dealt with by the // Visit the outgoing parameters.
// callee, but while GC'ing we artificially lower the number of
// arguments to zero and let the caller deal with it.
Object** parameters_base = &Memory::Object_at(sp()); Object** parameters_base = &Memory::Object_at(sp());
Object** parameters_limit = &Memory::Object_at( Object** parameters_limit = &Memory::Object_at(
fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
...@@ -635,21 +633,6 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const { ...@@ -635,21 +633,6 @@ void OptimizedFrame::Iterate(ObjectVisitor* v) const {
// Visit the return address in the callee and incoming arguments. // Visit the return address in the callee and incoming arguments.
IteratePc(v, pc_address(), code); IteratePc(v, pc_address(), code);
IterateArguments(v);
}
Object* JavaScriptFrame::GetParameter(int index) const {
ASSERT(index >= 0 && index < ComputeParametersCount());
const int offset = JavaScriptFrameConstants::kParam0Offset;
return Memory::Object_at(caller_sp() + offset - (index * kPointerSize));
}
int JavaScriptFrame::ComputeParametersCount() const {
Address base = caller_sp() + JavaScriptFrameConstants::kReceiverOffset;
Address limit = fp() + JavaScriptFrameConstants::kLastParameterOffset;
return static_cast<int>((base - limit) / kPointerSize);
} }
...@@ -669,27 +652,17 @@ Code* JavaScriptFrame::unchecked_code() const { ...@@ -669,27 +652,17 @@ Code* JavaScriptFrame::unchecked_code() const {
} }
int JavaScriptFrame::GetNumberOfIncomingArguments() const {
ASSERT(!SafeStackFrameIterator::is_active(isolate()) &&
isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
JSFunction* function = JSFunction::cast(this->function());
return function->shared()->formal_parameter_count();
}
Address JavaScriptFrame::GetCallerStackPointer() const { Address JavaScriptFrame::GetCallerStackPointer() const {
int arguments; return fp() + StandardFrameConstants::kCallerSPOffset;
if (SafeStackFrameIterator::is_active(isolate()) ||
isolate()->heap()->gc_state() != Heap::NOT_IN_GC) {
// If the we are currently iterating the safe stack the
// arguments for frames are traversed as if they were
// expression stack elements of the calling frame. The reason for
// this rather strange decision is that we cannot access the
// function during mark-compact GCs when objects may have been marked.
// In fact accessing heap objects (like function->shared() below)
// at all during GC is problematic.
arguments = 0;
} else {
// Compute the number of arguments by getting the number of formal
// parameters of the function. We must remember to take the
// receiver into account (+1).
JSFunction* function = JSFunction::cast(this->function());
arguments = function->shared()->formal_parameter_count() + 1;
}
const int offset = StandardFrameConstants::kCallerSPOffset;
return fp() + offset + (arguments * kPointerSize);
} }
...@@ -867,9 +840,7 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) { ...@@ -867,9 +840,7 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
const int arguments = Smi::cast(GetExpression(0))->value(); return fp() + StandardFrameConstants::kCallerSPOffset;
const int offset = StandardFrameConstants::kCallerSPOffset;
return fp() + offset + (arguments + 1) * kPointerSize;
} }
...@@ -1109,17 +1080,6 @@ void StandardFrame::IterateExpressions(ObjectVisitor* v) const { ...@@ -1109,17 +1080,6 @@ void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
void JavaScriptFrame::Iterate(ObjectVisitor* v) const { void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
IterateExpressions(v); IterateExpressions(v);
IteratePc(v, pc_address(), LookupCode()); IteratePc(v, pc_address(), LookupCode());
IterateArguments(v);
}
void JavaScriptFrame::IterateArguments(ObjectVisitor* v) const {
// Traverse callee-saved registers, receiver, and parameters.
const int kBaseOffset = JavaScriptFrameConstants::kLastParameterOffset;
const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset;
Object** base = &Memory::Object_at(fp() + kBaseOffset);
Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1;
v->VisitPointers(base, limit);
} }
......
...@@ -463,8 +463,11 @@ class JavaScriptFrame: public StandardFrame { ...@@ -463,8 +463,11 @@ class JavaScriptFrame: public StandardFrame {
inline void set_receiver(Object* value); inline void set_receiver(Object* value);
// Access the parameters. // Access the parameters.
Object* GetParameter(int index) const; inline Address GetParameterSlot(int index) const;
int ComputeParametersCount() const; inline Object* GetParameter(int index) const;
inline int ComputeParametersCount() const {
return GetNumberOfIncomingArguments();
}
// Check if this frame is a constructor frame invoked through 'new'. // Check if this frame is a constructor frame invoked through 'new'.
bool IsConstructor() const; bool IsConstructor() const;
...@@ -502,6 +505,8 @@ class JavaScriptFrame: public StandardFrame { ...@@ -502,6 +505,8 @@ class JavaScriptFrame: public StandardFrame {
virtual Address GetCallerStackPointer() const; virtual Address GetCallerStackPointer() const;
virtual int GetNumberOfIncomingArguments() const;
// Garbage collection support. Iterates over incoming arguments, // Garbage collection support. Iterates over incoming arguments,
// receiver, and any callee-saved registers. // receiver, and any callee-saved registers.
void IterateArguments(ObjectVisitor* v) const; void IterateArguments(ObjectVisitor* v) const;
...@@ -562,6 +567,10 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame { ...@@ -562,6 +567,10 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame {
explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator) explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator)
: JavaScriptFrame(iterator) { } : JavaScriptFrame(iterator) { }
virtual int GetNumberOfIncomingArguments() const {
return Smi::cast(GetExpression(0))->value();
}
virtual Address GetCallerStackPointer() const; virtual Address GetCallerStackPointer() const;
private: private:
......
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