Merge V8 at r7668: Initial merge by Git.
Change-Id: I1703c8b4f5c63052451a22cf3fb878abc9a0ec75
diff --git a/src/frames.cc b/src/frames.cc
index 79aa250..e0517c8 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -39,9 +39,6 @@
namespace v8 {
namespace internal {
-
-int SafeStackFrameIterator::active_count_ = 0;
-
// Iterator that supports traversing the stack handlers of a
// particular frame. Needs to know the top of the handler chain.
class StackHandlerIterator BASE_EMBEDDED {
@@ -73,23 +70,34 @@
#define INITIALIZE_SINGLETON(type, field) field##_(this),
StackFrameIterator::StackFrameIterator()
- : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
+ : isolate_(Isolate::Current()),
+ STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
frame_(NULL), handler_(NULL),
- thread_(Isolate::Current()->thread_local_top()),
+ thread_(isolate_->thread_local_top()),
fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
Reset();
}
-StackFrameIterator::StackFrameIterator(ThreadLocalTop* t)
- : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
+StackFrameIterator::StackFrameIterator(Isolate* isolate)
+ : isolate_(isolate),
+ STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
+ frame_(NULL), handler_(NULL),
+ thread_(isolate_->thread_local_top()),
+ fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
+ Reset();
+}
+StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
+ : isolate_(isolate),
+ STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
frame_(NULL), handler_(NULL), thread_(t),
fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) {
Reset();
}
StackFrameIterator::StackFrameIterator(Isolate* isolate,
bool use_top, Address fp, Address sp)
- : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
+ : isolate_(isolate),
+ STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
frame_(NULL), handler_(NULL),
- thread_(use_top ? isolate->thread_local_top() : NULL),
+ thread_(use_top ? isolate_->thread_local_top() : NULL),
fp_(use_top ? NULL : fp), sp_(sp),
advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
&StackFrameIterator::AdvanceWithoutHandler) {
@@ -147,7 +155,7 @@
state.sp = sp_;
state.pc_address =
reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_));
- type = StackFrame::ComputeType(&state);
+ type = StackFrame::ComputeType(isolate(), &state);
}
if (SingletonFor(type) == NULL) return;
frame_ = SingletonFor(type, &state);
@@ -188,6 +196,12 @@
}
+StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
+ : JavaScriptFrameIterator(isolate) {
+ if (!done() && !IsValidFrame()) Advance();
+}
+
+
void StackTraceFrameIterator::Advance() {
while (true) {
JavaScriptFrameIterator::Advance();
@@ -221,10 +235,24 @@
}
+SafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer(
+ Isolate* isolate)
+ : isolate_(isolate) {
+ isolate_->set_safe_stack_iterator_counter(
+ isolate_->safe_stack_iterator_counter() + 1);
+}
+
+
+SafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() {
+ isolate_->set_safe_stack_iterator_counter(
+ isolate_->safe_stack_iterator_counter() - 1);
+}
+
+
SafeStackFrameIterator::SafeStackFrameIterator(
Isolate* isolate,
Address fp, Address sp, Address low_bound, Address high_bound) :
- maintainer_(),
+ maintainer_(isolate),
stack_validator_(low_bound, high_bound),
is_valid_top_(IsValidTop(isolate, low_bound, high_bound)),
is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)),
@@ -233,6 +261,10 @@
iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
}
+bool SafeStackFrameIterator::is_active(Isolate* isolate) {
+ return isolate->safe_stack_iterator_counter() > 0;
+}
+
bool SafeStackFrameIterator::IsValidTop(Isolate* isolate,
Address low_bound, Address high_bound) {
@@ -333,10 +365,10 @@
#endif
-Code* StackFrame::GetSafepointData(Address pc,
+Code* StackFrame::GetSafepointData(Isolate* isolate,
+ Address pc,
SafepointEntry* safepoint_entry,
unsigned* stack_slots) {
- Isolate* isolate = Isolate::Current();
PcToCodeCache::PcToCodeCacheEntry* entry =
isolate->pc_to_code_cache()->GetCacheEntry(pc);
SafepointEntry cached_safepoint_entry = entry->safepoint_entry;
@@ -377,7 +409,7 @@
}
-StackFrame::Type StackFrame::ComputeType(State* state) {
+StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
ASSERT(state->fp != NULL);
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
return ARGUMENTS_ADAPTOR;
@@ -392,9 +424,8 @@
// frames as normal JavaScript frames to avoid having to look
// into the heap to determine the state. This is safe as long
// as nobody tries to GC...
- if (SafeStackFrameIterator::is_active()) return JAVA_SCRIPT;
- Code::Kind kind = GetContainingCode(Isolate::Current(),
- *(state->pc_address))->kind();
+ if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT;
+ Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind();
ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
}
@@ -405,7 +436,7 @@
StackFrame::Type StackFrame::GetCallerState(State* state) const {
ComputeCallerState(state);
- return ComputeType(state);
+ return ComputeType(isolate(), state);
}
@@ -465,7 +496,7 @@
void ExitFrame::Iterate(ObjectVisitor* v) const {
// The arguments are traversed as part of the expression stack of
// the calling frame.
- IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
+ IteratePc(v, pc_address(), LookupCode());
v->VisitPointer(&code_slot());
}
@@ -539,18 +570,16 @@
// Make sure that we're not doing "safe" stack frame iteration. We cannot
// possibly find pointers in optimized frames in that state.
- ASSERT(!SafeStackFrameIterator::is_active());
+ ASSERT(!SafeStackFrameIterator::is_active(isolate()));
// Compute the safepoint information.
unsigned stack_slots = 0;
SafepointEntry safepoint_entry;
Code* code = StackFrame::GetSafepointData(
- pc(), &safepoint_entry, &stack_slots);
+ isolate(), pc(), &safepoint_entry, &stack_slots);
unsigned slot_space = stack_slots * kPointerSize;
- // Visit the outgoing parameters. This is usually dealt with by the
- // callee, but while GC'ing we artificially lower the number of
- // arguments to zero and let the caller deal with it.
+ // Visit the outgoing parameters.
Object** parameters_base = &Memory::Object_at(sp());
Object** parameters_limit = &Memory::Object_at(
fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
@@ -604,21 +633,6 @@
// Visit the return address in the callee and incoming arguments.
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::kSavedRegistersOffset;
- return static_cast<int>((base - limit) / kPointerSize);
}
@@ -638,27 +652,17 @@
}
+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 {
- int arguments;
- if (SafeStackFrameIterator::is_active() ||
- 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);
+ return fp() + StandardFrameConstants::kCallerSPOffset;
}
@@ -670,7 +674,7 @@
void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
ASSERT(functions->length() == 0);
- Code* code_pointer = LookupCode(Isolate::Current());
+ Code* code_pointer = LookupCode();
int offset = static_cast<int>(pc() - code_pointer->address());
FrameSummary summary(receiver(),
JSFunction::cast(function()),
@@ -789,7 +793,7 @@
// back to a slow search in this case to find the original optimized
// code object.
if (!code->contains(pc())) {
- code = Isolate::Current()->pc_to_code_cache()->GcSafeFindCodeForPc(pc());
+ code = isolate()->pc_to_code_cache()->GcSafeFindCodeForPc(pc());
}
ASSERT(code != NULL);
ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
@@ -836,9 +840,7 @@
Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
- const int arguments = Smi::cast(GetExpression(0))->value();
- const int offset = StandardFrameConstants::kCallerSPOffset;
- return fp() + offset + (arguments + 1) * kPointerSize;
+ return fp() + StandardFrameConstants::kCallerSPOffset;
}
@@ -850,7 +852,7 @@
Code* ArgumentsAdaptorFrame::unchecked_code() const {
- return Isolate::Current()->builtins()->builtin(
+ return isolate()->builtins()->builtin(
Builtins::kArgumentsAdaptorTrampoline);
}
@@ -1045,14 +1047,14 @@
ASSERT(!it.done());
StackHandler* handler = it.handler();
ASSERT(handler->is_entry());
- handler->Iterate(v, LookupCode(Isolate::Current()));
+ handler->Iterate(v, LookupCode());
#ifdef DEBUG
// Make sure that the entry frame does not contain more than one
// stack handler.
it.Advance();
ASSERT(it.done());
#endif
- IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
+ IteratePc(v, pc_address(), LookupCode());
}
@@ -1069,7 +1071,7 @@
v->VisitPointers(base, reinterpret_cast<Object**>(address));
base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
// Traverse the pointers in the handler itself.
- handler->Iterate(v, LookupCode(Isolate::Current()));
+ handler->Iterate(v, LookupCode());
}
v->VisitPointers(base, limit);
}
@@ -1077,18 +1079,7 @@
void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
IterateExpressions(v);
- IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
- IterateArguments(v);
-}
-
-
-void JavaScriptFrame::IterateArguments(ObjectVisitor* v) const {
- // Traverse callee-saved registers, receiver, and parameters.
- const int kBaseOffset = JavaScriptFrameConstants::kSavedRegistersOffset;
- 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);
+ IteratePc(v, pc_address(), LookupCode());
}
@@ -1096,7 +1087,7 @@
// Internal frames only have object pointers on the expression stack
// as they never have any arguments.
IterateExpressions(v);
- IteratePc(v, pc_address(), LookupCode(Isolate::Current()));
+ IteratePc(v, pc_address(), LookupCode());
}