Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Unified Diff: src/frames.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/frames.cc
diff --git a/src/frames.cc b/src/frames.cc
index 53f510849ec0cd3ebb13e4397c1477637d7eebd7..0ca6991488464994be3300cf56e1ec47978036a4 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -88,39 +88,29 @@ class StackHandlerIterator BASE_EMBEDDED {
#define INITIALIZE_SINGLETON(type, field) field##_(this),
-StackFrameIterator::StackFrameIterator(Isolate* isolate)
+StackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
+ bool can_access_heap_objects)
: 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();
+ can_access_heap_objects_(can_access_heap_objects) {
}
-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)
- : isolate_(isolate),
- STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
- frame_(NULL), handler_(NULL),
- thread_(use_top ? isolate_->thread_local_top() : NULL),
- fp_(use_top ? NULL : fp), sp_(sp),
- advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
- &StackFrameIterator::AdvanceWithoutHandler) {
- if (use_top || fp != NULL) {
- Reset();
- }
+#undef INITIALIZE_SINGLETON
+
+
+StackFrameIterator::StackFrameIterator(Isolate* isolate)
+ : StackFrameIteratorBase(isolate, true) {
+ Reset(isolate->thread_local_top());
}
-#undef INITIALIZE_SINGLETON
+
+StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
+ : StackFrameIteratorBase(isolate, true) {
+ Reset(t);
+}
-void StackFrameIterator::AdvanceWithHandler() {
+void StackFrameIterator::Advance() {
ASSERT(!done());
// Compute the state of the calling frame before restoring
// callee-saved registers and unwinding handlers. This allows the
@@ -143,37 +133,17 @@ void StackFrameIterator::AdvanceWithHandler() {
}
-void StackFrameIterator::AdvanceWithoutHandler() {
- // A simpler version of Advance which doesn't care about handler.
- ASSERT(!done());
+void StackFrameIterator::Reset(ThreadLocalTop* top) {
StackFrame::State state;
- StackFrame::Type type = frame_->GetCallerState(&state);
- frame_ = SingletonFor(type, &state);
-}
-
-
-void StackFrameIterator::Reset() {
- StackFrame::State state;
- StackFrame::Type type;
- if (thread_ != NULL) {
- type = ExitFrame::GetStateForFramePointer(
- Isolate::c_entry_fp(thread_), &state);
- handler_ = StackHandler::FromAddress(
- Isolate::handler(thread_));
- } else {
- ASSERT(fp_ != NULL);
- state.fp = fp_;
- state.sp = sp_;
- state.pc_address = ResolveReturnAddressLocation(
- reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
- type = StackFrame::ComputeType(isolate(), &state);
- }
+ StackFrame::Type type = ExitFrame::GetStateForFramePointer(
+ Isolate::c_entry_fp(top), &state);
+ handler_ = StackHandler::FromAddress(Isolate::handler(top));
if (SingletonFor(type) == NULL) return;
frame_ = SingletonFor(type, &state);
}
-StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type,
+StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
StackFrame::State* state) {
if (type == StackFrame::NONE) return NULL;
StackFrame* result = SingletonFor(type);
@@ -183,7 +153,7 @@ StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type,
}
-StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) {
+StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
#define FRAME_TYPE_CASE(type, field) \
case StackFrame::type: result = &field##_; break;
@@ -202,6 +172,33 @@ StackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) {
// -------------------------------------------------------------------------
+JavaScriptFrameIterator::JavaScriptFrameIterator(
+ Isolate* isolate, StackFrame::Id id)
+ : iterator_(isolate) {
+ while (!done()) {
+ Advance();
+ if (frame()->id() == id) return;
+ }
+}
+
+
+void JavaScriptFrameIterator::Advance() {
+ do {
+ iterator_.Advance();
+ } while (!iterator_.done() && !iterator_.frame()->is_java_script());
+}
+
+
+void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
+ if (!frame()->has_adapted_arguments()) return;
+ iterator_.Advance();
+ ASSERT(iterator_.frame()->is_arguments_adaptor());
+}
+
+
+// -------------------------------------------------------------------------
+
+
StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
: JavaScriptFrameIterator(isolate) {
if (!done() && !IsValidFrame()) Advance();
@@ -228,85 +225,61 @@ bool StackTraceFrameIterator::IsValidFrame() {
// -------------------------------------------------------------------------
-bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) {
- if (!validator_.IsValid(fp)) return false;
- Address sp = ExitFrame::ComputeStackPointer(fp);
- if (!validator_.IsValid(sp)) return false;
- StackFrame::State state;
- ExitFrame::FillState(fp, sp, &state);
- if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) {
- return false;
- }
- return *state.pc_address != NULL;
-}
-
-
-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_(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)),
- is_working_iterator_(is_valid_top_ || is_valid_fp_),
- iteration_done_(!is_working_iterator_),
- iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
-}
+ StackFrameIteratorBase(isolate, false),
+ low_bound_(low_bound), high_bound_(high_bound) {
+ StackFrame::State state;
+ StackFrame::Type type;
+ ThreadLocalTop* top = isolate->thread_local_top();
+ if (IsValidTop(top)) {
+ type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
+ } else if (IsValidStackAddress(fp)) {
+ ASSERT(fp != NULL);
+ state.fp = fp;
+ state.sp = sp;
+ state.pc_address = ResolveReturnAddressLocation(
+ reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
+ type = StackFrame::ComputeType(this, &state);
+ } else {
+ return;
+ }
+ if (SingletonFor(type) == NULL) return;
+ frame_ = SingletonFor(type, &state);
-bool SafeStackFrameIterator::is_active(Isolate* isolate) {
- return isolate->safe_stack_iterator_counter() > 0;
+ if (!done()) Advance();
}
-bool SafeStackFrameIterator::IsValidTop(Isolate* isolate,
- Address low_bound, Address high_bound) {
- ThreadLocalTop* top = isolate->thread_local_top();
+bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
Address fp = Isolate::c_entry_fp(top);
- ExitFrameValidator validator(low_bound, high_bound);
- if (!validator.IsValidFP(fp)) return false;
+ if (!IsValidExitFrame(fp)) return false;
+ // There should be at least one JS_ENTRY stack handler.
return Isolate::handler(top) != NULL;
}
-void SafeStackFrameIterator::Advance() {
- ASSERT(is_working_iterator_);
+void SafeStackFrameIterator::AdvanceOneFrame() {
ASSERT(!done());
- StackFrame* last_frame = iterator_.frame();
+ StackFrame* last_frame = frame_;
Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
- // Before advancing to the next stack frame, perform pointer validity tests
- iteration_done_ = !IsValidFrame(last_frame) ||
- !CanIterateHandles(last_frame, iterator_.handler()) ||
- !IsValidCaller(last_frame);
- if (iteration_done_) return;
-
- iterator_.Advance();
- if (iterator_.done()) return;
- // Check that we have actually moved to the previous frame in the stack
- StackFrame* prev_frame = iterator_.frame();
- iteration_done_ = prev_frame->sp() < last_sp || prev_frame->fp() < last_fp;
-}
+ // Before advancing to the next stack frame, perform pointer validity tests.
+ if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
+ frame_ = NULL;
+ return;
+ }
+ // Advance to the previous frame.
+ StackFrame::State state;
+ StackFrame::Type type = frame_->GetCallerState(&state);
+ frame_ = SingletonFor(type, &state);
+ if (frame_ == NULL) return;
-bool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame,
- StackHandler* handler) {
- // If StackIterator iterates over StackHandles, verify that
- // StackHandlerIterator can be instantiated (see StackHandlerIterator
- // constructor.)
- return !is_valid_top_ || (frame->sp() <= handler->address());
+ // Check that we have actually moved to the previous frame in the stack.
+ if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
+ frame_ = NULL;
+ }
}
@@ -323,8 +296,7 @@ bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
// sure that caller FP address is valid.
Address caller_fp = Memory::Address_at(
frame->fp() + EntryFrameConstants::kCallerFPOffset);
- ExitFrameValidator validator(stack_validator_);
- if (!validator.IsValidFP(caller_fp)) return false;
+ if (!IsValidExitFrame(caller_fp)) return false;
} else if (frame->is_arguments_adaptor()) {
// See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
// the number of arguments is stored on stack as Smi. We need to check
@@ -337,38 +309,35 @@ bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
}
frame->ComputeCallerState(&state);
return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
- iterator_.SingletonFor(frame->GetCallerState(&state)) != NULL;
+ SingletonFor(frame->GetCallerState(&state)) != NULL;
}
-void SafeStackFrameIterator::Reset() {
- if (is_working_iterator_) {
- iterator_.Reset();
- iteration_done_ = false;
+bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
+ if (!IsValidStackAddress(fp)) return false;
+ Address sp = ExitFrame::ComputeStackPointer(fp);
+ if (!IsValidStackAddress(sp)) return false;
+ StackFrame::State state;
+ ExitFrame::FillState(fp, sp, &state);
+ if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) {
+ return false;
}
+ return *state.pc_address != NULL;
}
-// -------------------------------------------------------------------------
-
-
-SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
- Isolate* isolate,
- Address fp, Address sp, Address low_bound, Address high_bound) :
- SafeJavaScriptFrameIterator(isolate, fp, sp, low_bound, high_bound) {
- if (!done() && !frame()->is_java_script()) Advance();
-}
-
-
-void SafeStackTraceFrameIterator::Advance() {
+void SafeStackFrameIterator::Advance() {
while (true) {
- SafeJavaScriptFrameIterator::Advance();
+ AdvanceOneFrame();
if (done()) return;
- if (frame()->is_java_script()) return;
+ if (frame_->is_java_script()) return;
}
}
+// -------------------------------------------------------------------------
+
+
Code* StackFrame::GetSafepointData(Isolate* isolate,
Address inner_pointer,
SafepointEntry* safepoint_entry,
@@ -425,7 +394,8 @@ void StackFrame::SetReturnAddressLocationResolver(
}
-StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
+StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
+ State* state) {
ASSERT(state->fp != NULL);
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
return ARGUMENTS_ADAPTOR;
@@ -440,8 +410,9 @@ StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
// 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(isolate)) return JAVA_SCRIPT;
- Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind();
+ if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT;
+ Code::Kind kind = GetContainingCode(iterator->isolate(),
+ *(state->pc_address))->kind();
ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
}
@@ -449,10 +420,16 @@ StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
}
+#ifdef DEBUG
+bool StackFrame::can_access_heap_objects() const {
+ return iterator_->can_access_heap_objects_;
+}
+#endif
+
StackFrame::Type StackFrame::GetCallerState(State* state) const {
ComputeCallerState(state);
- return ComputeType(isolate(), state);
+ return ComputeType(iterator_, state);
}
@@ -545,6 +522,11 @@ StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
}
+Address ExitFrame::ComputeStackPointer(Address fp) {
+ return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
+}
+
+
void ExitFrame::FillState(Address fp, Address sp, State* state) {
state->sp = sp;
state->fp = fp;
@@ -607,7 +589,7 @@ bool StandardFrame::IsExpressionInsideHandler(int n) const {
void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
// 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(isolate()));
+ ASSERT(can_access_heap_objects());
// Compute the safepoint information.
unsigned stack_slots = 0;
@@ -734,12 +716,12 @@ int JavaScriptFrame::GetArgumentsLength() const {
Code* JavaScriptFrame::unchecked_code() const {
JSFunction* function = JSFunction::cast(this->function());
- return function->unchecked_code();
+ return function->code();
}
int JavaScriptFrame::GetNumberOfIncomingArguments() const {
- ASSERT(!SafeStackFrameIterator::is_active(isolate()) &&
+ ASSERT(can_access_heap_objects() &&
isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
JSFunction* function = JSFunction::cast(this->function());
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698