Address JavaScriptFrame::GetCallerStackPointer() const {
int arguments;
- if (Heap::gc_state() != Heap::NOT_IN_GC) {
+ if (Heap::gc_state() != Heap::NOT_IN_GC || disable_heap_access_) {
// The arguments for cooked 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
Address JavaScriptFrame::GetCallerStackPointer() const {
int arguments;
- if (Heap::gc_state() != Heap::NOT_IN_GC) {
+ if (Heap::gc_state() != Heap::NOT_IN_GC || disable_heap_access_) {
// The arguments for cooked 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
}
-inline bool JavaScriptFrame::is_at_function() const {
- Object* result = function_slot_object();
- // Verify that frame points at correct JS function object.
- // We are verifying that function object address and
- // the underlying map object address are valid, and that
- // function is really a function.
- return Heap::Contains(reinterpret_cast<Address>(result)) &&
- result->IsHeapObject() &&
- Heap::Contains(HeapObject::cast(result)->map()) &&
- result->IsJSFunction();
-}
-
-
inline Object* JavaScriptFrame::function() const {
Object* result = function_slot_object();
ASSERT(result->IsJSFunction());
if (use_top || fp != NULL) {
Reset();
}
+ JavaScriptFrame_.DisableHeapAccess();
}
#undef INITIALIZE_SINGLETON
bool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
- return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp()) &&
- // JavaScriptFrame uses function shared info to advance, hence it must
- // point to a valid function object.
- (!frame->is_java_script() ||
- reinterpret_cast<JavaScriptFrame*>(frame)->is_at_function());
+ return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
}
SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
Address fp, Address sp, Address low_bound, Address high_bound) :
SafeJavaScriptFrameIterator(fp, sp, low_bound, high_bound) {
- if (!done() && !frame()->is_at_function()) Advance();
+ if (!done() && !frame()->is_java_script()) Advance();
}
while (true) {
SafeJavaScriptFrameIterator::Advance();
if (done()) return;
- if (frame()->is_at_function()) return;
+ if (frame()->is_java_script()) return;
}
}
#endif
virtual Type type() const { return JAVA_SCRIPT; }
// Accessors.
- inline bool is_at_function() const;
inline Object* function() const;
inline Object* receiver() const;
inline void set_receiver(Object* value);
protected:
explicit JavaScriptFrame(StackFrameIterator* iterator)
- : StandardFrame(iterator) { }
+ : StandardFrame(iterator), disable_heap_access_(false) { }
virtual Address GetCallerStackPointer() const;
+ // When this mode is enabled it is not allowed to access heap objects.
+ // This is a special mode used when gathering stack samples in profiler.
+ // A shortcoming is that caller's SP value will be calculated incorrectly
+ // (see GetCallerStackPointer implementation), but it is not used for stack
+ // sampling.
+ void DisableHeapAccess() { disable_heap_access_ = true; }
+
private:
+ bool disable_heap_access_;
inline Object* function_slot_object() const;
friend class StackFrameIterator;