diff options
Diffstat (limited to 'deps/v8/src/frames.cc')
-rw-r--r-- | deps/v8/src/frames.cc | 94 |
1 files changed, 65 insertions, 29 deletions
diff --git a/deps/v8/src/frames.cc b/deps/v8/src/frames.cc index 8561e557e8..7e55833b45 100644 --- a/deps/v8/src/frames.cc +++ b/deps/v8/src/frames.cc @@ -19,7 +19,6 @@ namespace v8 { namespace internal { - ReturnAddressLocationResolver StackFrame::return_address_location_resolver_ = NULL; @@ -185,7 +184,7 @@ bool StackTraceFrameIterator::IsValidFrame() { Object* script = frame()->function()->shared()->script(); // Don't show functions from native scripts to user. return (script->IsScript() && - Script::TYPE_NATIVE != Script::cast(script)->type()->value()); + Script::TYPE_NATIVE != Script::cast(script)->type()); } @@ -407,42 +406,58 @@ void StackFrame::SetReturnAddressLocationResolver( StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, State* state) { DCHECK(state->fp != NULL); - if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { - return ARGUMENTS_ADAPTOR; + + if (!iterator->can_access_heap_objects_) { + // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really + // means that we are being called from the profiler, which can interrupt + // the VM with a signal at any arbitrary instruction, with essentially + // anything on the stack. So basically none of these checks are 100% + // reliable. + if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { + // An adapter frame has a special SMI constant for the context and + // is not distinguished through the marker. + return ARGUMENTS_ADAPTOR; + } + Object* marker = + Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); + if (marker->IsSmi()) { + return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); + } else { + return JAVA_SCRIPT; + } } - // The marker and function offsets overlap. If the marker isn't a - // smi then the frame is a JavaScript frame -- and the marker is - // really the function. - const int offset = StandardFrameConstants::kMarkerOffset; - Object* marker = Memory::Object_at(state->fp + offset); - if (!marker->IsSmi()) { - // If we're using a "safe" stack iterator, we treat optimized - // 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 (!iterator->can_access_heap_objects_) return JAVA_SCRIPT; - Code* code_obj = - GetContainingCode(iterator->isolate(), *(state->pc_address)); + + // Look up the code object to figure out the type of the stack frame. + Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address)); + + Object* marker = + Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); + if (code_obj != nullptr) { switch (code_obj->kind()) { case Code::FUNCTION: return JAVA_SCRIPT; - - case Code::HANDLER: -#ifdef DEBUG - if (!code_obj->is_hydrogen_stub()) { - // There's currently no support for non-hydrogen stub handlers. If - // you this, you'll have to implement it yourself. - UNREACHABLE(); - } -#endif case Code::OPTIMIZED_FUNCTION: return OPTIMIZED; - + case Code::HANDLER: + if (!marker->IsSmi()) { + // Only hydrogen code stub handlers can have a non-SMI marker. + DCHECK(code_obj->is_hydrogen_stub()); + return OPTIMIZED; + } + break; // Marker encodes the frame type. default: - UNREACHABLE(); - return JAVA_SCRIPT; + break; // Marker encodes the frame type. } } + + if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { + // An adapter frame has a special SMI constant for the context and + // is not distinguished through the marker. + return ARGUMENTS_ADAPTOR; + } + + // Didn't find a code object, or the code kind wasn't specific enough. + // The marker should encode the frame type. return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); } @@ -727,6 +742,13 @@ bool JavaScriptFrame::IsConstructor() const { } +bool JavaScriptFrame::HasInlinedFrames() { + List<JSFunction*> functions(1); + GetFunctions(&functions); + return functions.length() > 1; +} + + Object* JavaScriptFrame::GetOriginalConstructor() const { Address fp = caller_fp(); if (has_adapted_arguments()) { @@ -879,6 +901,15 @@ void JavaScriptFrame::RestoreOperandStack(FixedArray* store) { } +FrameSummary::FrameSummary(Object* receiver, JSFunction* function, Code* code, + int offset, bool is_constructor) + : receiver_(receiver, function->GetIsolate()), + function_(function), + code_(code), + offset_(offset), + is_constructor_(is_constructor) {} + + void FrameSummary::Print() { PrintF("receiver: "); receiver_->ShortPrint(); @@ -1429,6 +1460,11 @@ Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object, Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( Address inner_pointer) { Heap* heap = isolate_->heap(); + if (!heap->code_space()->Contains(inner_pointer) && + !heap->lo_space()->Contains(inner_pointer)) { + return nullptr; + } + // Check if the inner pointer points into a large object chunk. LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); if (large_page != NULL) { |