13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ast.h" 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "frames-inl.h" 33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "full-codegen.h" 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "lazy-instance.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "mark-compact.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "safepoint-table.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopeinfo.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "allocation-inl.h" 413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic ReturnAddressLocationResolver return_address_location_resolver = NULL; 473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Resolves pc_address through the resolution address function if one is set. 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic inline Address* ResolveReturnAddressLocation(Address* pc_address) { 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (return_address_location_resolver == NULL) { 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return pc_address; 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<Address*>( 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return_address_location_resolver( 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<uintptr_t>(pc_address))); 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Iterator that supports traversing the stack handlers of a 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// particular frame. Needs to know the top of the handler chain. 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StackHandlerIterator BASE_EMBEDDED { 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandlerIterator(const StackFrame* frame, StackHandler* handler) 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : limit_(frame->fp()), handler_(handler) { 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure the handler has already been unwound to this frame. 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(frame->sp() <= handler->address()); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler() const { return handler_; } 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool done() { 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return handler_ == NULL || handler_->address() > limit_; 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Advance() { 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handler_ = handler_->next(); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Address limit_; 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler_; 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define INITIALIZE_SINGLETON(type, field) field##_(this), 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrameIterator::StackFrameIterator() 928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : isolate_(Isolate::Current()), 938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch frame_(NULL), handler_(NULL), 958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_(isolate_->thread_local_top()), 968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { 978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Reset(); 988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 998b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackFrameIterator::StackFrameIterator(Isolate* isolate) 1008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : isolate_(isolate), 1018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block frame_(NULL), handler_(NULL), 1038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_(isolate_->thread_local_top()), 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1078b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) 1088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : isolate_(isolate), 1098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_(NULL), handler_(NULL), thread_(t), 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fp_(NULL), sp_(NULL), advance_(&StackFrameIterator::AdvanceWithHandler) { 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 11444f0eee88ff00398ff7f715fab053374d808c90dSteve BlockStackFrameIterator::StackFrameIterator(Isolate* isolate, 11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool use_top, Address fp, Address sp) 1168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : isolate_(isolate), 1178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_(NULL), handler_(NULL), 1198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch thread_(use_top ? isolate_->thread_local_top() : NULL), 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fp_(use_top ? NULL : fp), sp_(sp), 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &StackFrameIterator::AdvanceWithoutHandler) { 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (use_top || fp != NULL) { 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Reset(); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef INITIALIZE_SINGLETON 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackFrameIterator::AdvanceWithHandler() { 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the state of the calling frame before restoring 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // callee-saved registers and unwinding handlers. This allows the 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // frame code that computes the caller state to access the top 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler and the value of any callee-saved register if needed. 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::State state; 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::Type type = frame_->GetCallerState(&state); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unwind handlers corresponding to the current frame. 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandlerIterator it(frame_, handler_); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!it.done()) it.Advance(); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handler_ = it.handler(); 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance to the calling frame. 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_ = SingletonFor(type, &state); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When we're done iterating over the stack frames, the handler 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // chain must have been completely unwound. 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done() || handler_ == NULL); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackFrameIterator::AdvanceWithoutHandler() { 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // A simpler version of Advance which doesn't care about handler. 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::State state; 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::Type type = frame_->GetCallerState(&state); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_ = SingletonFor(type, &state); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackFrameIterator::Reset() { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::State state; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::Type type; 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (thread_ != NULL) { 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block type = ExitFrame::GetStateForFramePointer( 16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::c_entry_fp(thread_), &state); 16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block handler_ = StackHandler::FromAddress( 17044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::handler(thread_)); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(fp_ != NULL); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state.fp = fp_; 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state.sp = sp_; 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch state.pc_address = ResolveReturnAddressLocation( 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_))); 1778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch type = StackFrame::ComputeType(isolate(), &state); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (SingletonFor(type) == NULL) return; 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_ = SingletonFor(type, &state); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type, 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::State* state) { 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (type == StackFrame::NONE) return NULL; 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* result = SingletonFor(type); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(result != NULL); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->state_ = *state; 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrame* StackFrameIterator::SingletonFor(StackFrame::Type type) { 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define FRAME_TYPE_CASE(type, field) \ 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case StackFrame::type: result = &field##_; break; 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* result = NULL; 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (type) { 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case StackFrame::NONE: return NULL; 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: break; 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef FRAME_TYPE_CASE 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackTraceFrameIterator::StackTraceFrameIterator() { 2144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (!done() && !IsValidFrame()) Advance(); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2188b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) 2198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : JavaScriptFrameIterator(isolate) { 2208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (!done() && !IsValidFrame()) Advance(); 2218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 2228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackTraceFrameIterator::Advance() { 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIterator::Advance(); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (done()) return; 2284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (IsValidFrame()) return; 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2324515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool StackTraceFrameIterator::IsValidFrame() { 2334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (!frame()->function()->IsJSFunction()) return false; 2344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Object* script = JSFunction::cast(frame()->function())->shared()->script(); 2354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Don't show functions from native scripts to user. 2364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return (script->IsScript() && 2374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Script::TYPE_NATIVE != Script::cast(script)->type()->value()); 2384515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 2394515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2440d5e116f6aee03185f237311a943491bb079a768Kristian Monsenbool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) { 2450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!validator_.IsValid(fp)) return false; 2460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address sp = ExitFrame::ComputeStackPointer(fp); 2470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!validator_.IsValid(sp)) return false; 2480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen StackFrame::State state; 2490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ExitFrame::FillState(fp, sp, &state); 2500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { 2510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return false; 2520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 2530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return *state.pc_address != NULL; 2540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 2550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 2560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 2578b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochSafeStackFrameIterator::ActiveCountMaintainer::ActiveCountMaintainer( 2588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate) 2598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : isolate_(isolate) { 2608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate_->set_safe_stack_iterator_counter( 2618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate_->safe_stack_iterator_counter() + 1); 2628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 2638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2658b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochSafeStackFrameIterator::ActiveCountMaintainer::~ActiveCountMaintainer() { 2668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate_->set_safe_stack_iterator_counter( 2678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate_->safe_stack_iterator_counter() - 1); 2688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 2698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSafeStackFrameIterator::SafeStackFrameIterator( 27244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate, 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp, Address sp, Address low_bound, Address high_bound) : 2748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch maintainer_(isolate), 2750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen stack_validator_(low_bound, high_bound), 27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_valid_top_(IsValidTop(isolate, low_bound, high_bound)), 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_working_iterator_(is_valid_top_ || is_valid_fp_), 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iteration_done_(!is_working_iterator_), 28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block iterator_(isolate, is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochbool SafeStackFrameIterator::is_active(Isolate* isolate) { 2848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return isolate->safe_stack_iterator_counter() > 0; 2858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 2868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool SafeStackFrameIterator::IsValidTop(Isolate* isolate, 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address low_bound, Address high_bound) { 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ThreadLocalTop* top = isolate->thread_local_top(); 29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address fp = Isolate::c_entry_fp(top); 2920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ExitFrameValidator validator(low_bound, high_bound); 2930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!validator.IsValidFP(fp)) return false; 29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::handler(top) != NULL; 2950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 2960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 2970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SafeStackFrameIterator::Advance() { 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(is_working_iterator_); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!done()); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* last_frame = iterator_.frame(); 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Before advancing to the next stack frame, perform pointer validity tests 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iteration_done_ = !IsValidFrame(last_frame) || 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !CanIterateHandles(last_frame, iterator_.handler()) || 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !IsValidCaller(last_frame); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (iteration_done_) return; 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_.Advance(); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (iterator_.done()) return; 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that we have actually moved to the previous frame in the stack 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame* prev_frame = iterator_.frame(); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iteration_done_ = prev_frame->sp() < last_sp || prev_frame->fp() < last_fp; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool SafeStackFrameIterator::CanIterateHandles(StackFrame* frame, 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler) { 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If StackIterator iterates over StackHandles, verify that 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // StackHandlerIterator can be instantiated (see StackHandlerIterator 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constructor.) 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !is_valid_top_ || (frame->sp() <= handler->address()); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const { 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp()); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::State state; 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (frame->is_entry() || frame->is_entry_construct()) { 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // See EntryFrame::GetCallerState. It computes the caller FP address 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and calls ExitFrame::GetStateForFramePointer on it. We need to be 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sure that caller FP address is valid. 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address caller_fp = Memory::Address_at( 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame->fp() + EntryFrameConstants::kCallerFPOffset); 3390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ExitFrameValidator validator(stack_validator_); 3400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!validator.IsValidFP(caller_fp)) return false; 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (frame->is_arguments_adaptor()) { 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the number of arguments is stored on stack as Smi. We need to check 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that it really an Smi. 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)-> 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GetExpression(0); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!number_of_args->IsSmi()) { 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame->ComputeCallerState(&state); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) && 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_.SingletonFor(frame->GetCallerState(&state)) != NULL; 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SafeStackFrameIterator::Reset() { 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_working_iterator_) { 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_.Reset(); 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iteration_done_ = false; 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSafeStackTraceFrameIterator::SafeStackTraceFrameIterator( 36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate, 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp, Address sp, Address low_bound, Address high_bound) : 37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block SafeJavaScriptFrameIterator(isolate, fp, sp, low_bound, high_bound) { 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!done() && !frame()->is_java_script()) Advance(); 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SafeStackTraceFrameIterator::Advance() { 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SafeJavaScriptFrameIterator::Advance(); 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (done()) return; 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (frame()->is_java_script()) return; 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3858b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochCode* StackFrame::GetSafepointData(Isolate* isolate, 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address inner_pointer, 387b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry* safepoint_entry, 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned* stack_slots) { 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); 391b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (!entry->safepoint_entry.is_valid()) { 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); 393b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ASSERT(entry->safepoint_entry.is_valid()); 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(entry->safepoint_entry.Equals( 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch entry->code->GetSafepointEntry(inner_pointer))); 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fill in the results and return the code. 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code = entry->code; 401b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch *safepoint_entry = entry->safepoint_entry; 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *stack_slots = code->stack_slots(); 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return code; 404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackFrame::HasHandler() const { 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandlerIterator it(this, top_handler()); 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !it.done(); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool GcSafeCodeContains(HeapObject* object, Address addr); 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid StackFrame::IteratePc(ObjectVisitor* v, 41980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Address* pc_address, 42080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code* holder) { 42180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Address pc = *pc_address; 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(GcSafeCodeContains(holder, pc)); 42380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); 42480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* code = holder; 42580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v->VisitPointer(&code); 42680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (code != holder) { 42780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen holder = reinterpret_cast<Code*>(code); 42880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen pc = holder->instruction_start() + pc_offset; 42980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen *pc_address = pc; 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StackFrame::SetReturnAddressLocationResolver( 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ReturnAddressLocationResolver resolver) { 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(return_address_location_resolver == NULL); 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return_address_location_resolver = resolver; 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4418b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochStackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) { 44280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(state->fp != NULL); 44380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 44480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return ARGUMENTS_ADAPTOR; 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 44680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // The marker and function offsets overlap. If the marker isn't a 44780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // smi then the frame is a JavaScript frame -- and the marker is 44880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // really the function. 44980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const int offset = StandardFrameConstants::kMarkerOffset; 45080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Object* marker = Memory::Object_at(state->fp + offset); 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!marker->IsSmi()) { 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // If we're using a "safe" stack iterator, we treat optimized 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // frames as normal JavaScript frames to avoid having to look 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // into the heap to determine the state. This is safe as long 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // as nobody tries to GC... 4568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (SafeStackFrameIterator::is_active(isolate)) return JAVA_SCRIPT; 4578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code::Kind kind = GetContainingCode(isolate, *(state->pc_address))->kind(); 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 46180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrame::Type StackFrame::GetCallerState(State* state) const { 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ComputeCallerState(state); 4688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return ComputeType(isolate(), state); 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* EntryFrame::unchecked_code() const { 47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return HEAP->raw_unchecked_js_entry_code(); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid EntryFrame::ComputeCallerState(State* state) const { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GetCallerState(state); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid EntryFrame::SetCallerFp(Address caller_fp) { 4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const int offset = EntryFrameConstants::kCallerFPOffset; 4846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Memory::Address_at(this->fp() + offset) = caller_fp; 4856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackFrame::Type EntryFrame::GetCallerState(State* state) const { 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int offset = EntryFrameConstants::kCallerFPOffset; 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp = Memory::Address_at(this->fp() + offset); 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ExitFrame::GetStateForFramePointer(fp, state); 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 495756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* EntryConstructFrame::unchecked_code() const { 49644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return HEAP->raw_unchecked_js_construct_entry_code(); 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 500d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockObject*& ExitFrame::code_slot() const { 501d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const int offset = ExitFrameConstants::kCodeOffset; 502d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return Memory::Object_at(fp() + offset); 503d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 504d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 505d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 506756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* ExitFrame::unchecked_code() const { 507756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return reinterpret_cast<Code*>(code_slot()); 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ExitFrame::ComputeCallerState(State* state) const { 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up the caller state. 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state->sp = caller_sp(); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch state->pc_address = ResolveReturnAddressLocation( 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5206ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid ExitFrame::SetCallerFp(Address caller_fp) { 5216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; 5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 5236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 52580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid ExitFrame::Iterate(ObjectVisitor* v) const { 52680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // The arguments are traversed as part of the expression stack of 52780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the calling frame. 5288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch IteratePc(v, pc_address(), LookupCode()); 52980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v->VisitPointer(&code_slot()); 53080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 53180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 53280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress ExitFrame::GetCallerStackPointer() const { 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return fp() + ExitFrameConstants::kCallerSPDisplacement; 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5380d5e116f6aee03185f237311a943491bb079a768Kristian MonsenStackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { 5390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (fp == 0) return NONE; 5400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Address sp = ComputeStackPointer(fp); 5410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FillState(fp, sp, state); 5420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(*state->pc_address != NULL); 5430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return EXIT; 5440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5470d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid ExitFrame::FillState(Address fp, Address sp, State* state) { 5480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen state->sp = sp; 5490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen state->fp = fp; 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch state->pc_address = ResolveReturnAddressLocation( 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address*>(sp - 1 * kPointerSize)); 5520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress StandardFrame::GetExpressionAddress(int n) const { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int offset = StandardFrameConstants::kExpressionsOffset; 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return fp() + offset - n * kPointerSize; 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochObject* StandardFrame::GetExpression(Address fp, int index) { 5623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Memory::Object_at(GetExpressionAddress(fp, index)); 5633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochAddress StandardFrame::GetExpressionAddress(Address fp, int n) { 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int offset = StandardFrameConstants::kExpressionsOffset; 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return fp + offset - n * kPointerSize; 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint StandardFrame::ComputeExpressionsCount() const { 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int offset = 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StandardFrameConstants::kExpressionsOffset + kPointerSize; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address base = fp() + offset; 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address limit = sp(); 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(base >= limit); // stack grows downwards 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Include register-allocated locals in number of expressions. 579d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return static_cast<int>((base - limit) / kPointerSize); 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StandardFrame::ComputeCallerState(State* state) const { 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state->sp = caller_sp(); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block state->fp = caller_fp(); 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch state->pc_address = ResolveReturnAddressLocation( 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Address*>(ComputePCAddress(fp()))); 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5916ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid StandardFrame::SetCallerFp(Address caller_fp) { 5926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 5936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block caller_fp; 5946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 5956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StandardFrame::IsExpressionInsideHandler(int n) const { 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address = GetExpressionAddress(n); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (it.handler()->includes(address)) return true; 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid OptimizedFrame::Iterate(ObjectVisitor* v) const { 607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 608b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Make sure that optimized frames do not contain any stack handlers. 609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StackHandlerIterator it(this, top_handler()); 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(it.done()); 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Make sure that we're not doing "safe" stack frame iteration. We cannot 614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // possibly find pointers in optimized frames in that state. 6158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(!SafeStackFrameIterator::is_active(isolate())); 616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compute the safepoint information. 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned stack_slots = 0; 619b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry safepoint_entry; 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code = StackFrame::GetSafepointData( 6218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate(), pc(), &safepoint_entry, &stack_slots); 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned slot_space = stack_slots * kPointerSize; 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // Visit the outgoing parameters. 625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object** parameters_base = &Memory::Object_at(sp()); 626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object** parameters_limit = &Memory::Object_at( 627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); 628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 629b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Visit the parameters that may be on top of the saved registers. 630b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (safepoint_entry.argument_count() > 0) { 631b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch v->VisitPointers(parameters_base, 632b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch parameters_base + safepoint_entry.argument_count()); 633b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch parameters_base += safepoint_entry.argument_count(); 634b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 635b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 636b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Skip saved double registers. 637b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (safepoint_entry.has_doubles()) { 638b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch parameters_base += DoubleRegister::kNumAllocatableRegisters * 639b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch kDoubleSize / kPointerSize; 640b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 641b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Visit the registers that contain pointers if any. 643b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (safepoint_entry.HasRegisters()) { 644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = kNumSafepointRegisters - 1; i >=0; i--) { 645b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (safepoint_entry.HasRegisterAt(i)) { 646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i); 647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v->VisitPointer(parameters_base + reg_stack_index); 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Skip the words containing the register values. 651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch parameters_base += kNumSafepointRegisters; 652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 653b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We're done dealing with the register bits. 655b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t* safepoint_bits = safepoint_entry.bits(); 656b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch safepoint_bits += kNumSafepointRegisters >> kBitsPerByteLog2; 657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Visit the rest of the parameters. 659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v->VisitPointers(parameters_base, parameters_limit); 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Visit pointer spill slots and locals. 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (unsigned index = 0; index < stack_slots; index++) { 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int byte_index = index >> kBitsPerByteLog2; 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int bit_index = index & (kBitsPerByte - 1); 665b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v->VisitPointer(parameters_limit + index); 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Visit the context and the function. 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object** fixed_base = &Memory::Object_at( 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch fp() + JavaScriptFrameConstants::kFunctionOffset); 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object** fixed_limit = &Memory::Object_at(fp()); 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v->VisitPointers(fixed_base, fixed_limit); 675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Visit the return address in the callee and incoming arguments. 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch IteratePc(v, pc_address(), code); 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool JavaScriptFrame::IsConstructor() const { 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp = caller_fp(); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (has_adapted_arguments()) { 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip the arguments adaptor frame and look at the real caller. 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return IsConstructFrame(fp); 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint JavaScriptFrame::GetArgumentsLength() const { 6923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If there is an arguments adaptor frame get the arguments length from it. 6933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (has_adapted_arguments()) { 6943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return Smi::cast(GetExpression(caller_fp(), 0))->value(); 6953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return GetNumberOfIncomingArguments(); 6973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 701756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* JavaScriptFrame::unchecked_code() const { 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* function = JSFunction::cast(this->function()); 703756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return function->unchecked_code(); 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochint JavaScriptFrame::GetNumberOfIncomingArguments() const { 7088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(!SafeStackFrameIterator::is_active(isolate()) && 7098b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate()->heap()->gc_state() == Heap::NOT_IN_GC); 7108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7118b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JSFunction* function = JSFunction::cast(this->function()); 7128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return function->shared()->formal_parameter_count(); 7138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 7148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 71680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenAddress JavaScriptFrame::GetCallerStackPointer() const { 7178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return fp() + StandardFrameConstants::kCallerSPOffset; 71880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 71980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { 722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(functions->length() == 0); 723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch functions->Add(JSFunction::cast(function())); 724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid JavaScriptFrame::Summarize(List<FrameSummary>* functions) { 728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(functions->length() == 0); 7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* code_pointer = LookupCode(); 730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset = static_cast<int>(pc() - code_pointer->address()); 731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameSummary summary(receiver(), 732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction::cast(function()), 733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_pointer, 734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch offset, 735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch IsConstructor()); 736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch functions->Add(summary); 737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid JavaScriptFrame::PrintTop(FILE* file, 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool print_args, 7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool print_line_number) { 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // constructor calls 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HandleScope scope; 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AssertNoAllocation no_allocation; 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrameIterator it; 7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!it.done()) { 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (it.frame()->is_java_script()) { 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JavaScriptFrame* frame = it.frame(); 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (frame->IsConstructor()) PrintF(file, "new "); 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // function name 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* maybe_fun = frame->function(); 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (maybe_fun->IsJSFunction()) { 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSFunction* fun = JSFunction::cast(maybe_fun); 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fun->PrintName(); 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* js_code = frame->unchecked_code(); 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address pc = frame->pc(); 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int code_offset = 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<int>(pc - js_code->instruction_start()); 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("+%d", code_offset); 7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SharedFunctionInfo* shared = fun->shared(); 7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (print_line_number) { 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = Code::cast( 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::internal::Isolate::Current()->heap()->FindCodeObject(pc)); 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int source_pos = code->SourcePosition(pc); 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* maybe_script = shared->script(); 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (maybe_script->IsScript()) { 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Script> script(Script::cast(maybe_script)); 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int line = GetScriptLineNumberSafe(script, source_pos) + 1; 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* script_name_raw = script->name(); 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (script_name_raw->IsString()) { 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch String* script_name = String::cast(script->name()); 7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmartArrayPointer<char> c_script_name = 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch script_name->ToCString(DISALLOW_NULLS, 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ROBUST_STRING_TRAVERSAL); 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(file, " at %s:%d", *c_script_name, line); 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(file, "at <unknown>:%d", line); 7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(file, " at <unknown>:<unknown>"); 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("<unknown>"); 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (print_args) { 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // function arguments 7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (we are intentionally only printing the actually 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // supplied parameters, not all parameters required) 7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(file, "(this="); 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame->receiver()->ShortPrint(file); 7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int length = frame->ComputeParametersCount(); 7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < length; i++) { 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(file, ", "); 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame->GetParameter(i)->ShortPrint(file); 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(file, ")"); 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Advance(); 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FrameSummary::Print() { 809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("receiver: "); 810b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch receiver_->ShortPrint(); 811b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("\nfunction: "); 812b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_->shared()->DebugName()->ShortPrint(); 813b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("\ncode: "); 814b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_->ShortPrint(); 815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); 816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); 817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("\npc: %d\n", offset_); 818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid OptimizedFrame::Summarize(List<FrameSummary>* frames) { 822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(frames->length() == 0); 823b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(is_optimized()); 824b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int deopt_index = Safepoint::kNoDeoptimizationIndex; 826b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // BUG(3243555): Since we don't have a lazy-deopt registered at 829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // throw-statements, we can't use the translation at the call-site of 830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // throw. An entry with no deoptimization index indicates a call-site 831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // without a lazy-deopt. As a consequence we are not allowed to inline 832b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // functions containing throw. 833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (deopt_index == Safepoint::kNoDeoptimizationIndex) { 834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JavaScriptFrame::Summarize(frames); 835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 837b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 838b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationIterator it(data->TranslationByteArray(), 839b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->TranslationIndex(deopt_index)->value()); 840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(opcode == Translation::BEGIN); 8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Next(); // Drop frame count. 8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count = it.Next(); 844b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We create the summary in reverse order because the frames 846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // in the deoptimization translation are ordered bottom-to-top. 8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_constructor = IsConstructor(); 8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int i = jsframe_count; 849b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch while (i > 0) { 850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch opcode = static_cast<Translation::Opcode>(it.Next()); 8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (opcode == Translation::JS_FRAME) { 852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i--; 853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int ast_id = it.Next(); 854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int function_id = it.Next(); 855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Next(); // Skip height. 856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function = 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction::cast(data->LiteralArray()->get(function_id)); 858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The translation commands are ordered and the receiver is always 860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // at the first position. Since we are always at a call when we need 861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // to construct a stack trace, the receiver is always in a stack slot. 862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch opcode = static_cast<Translation::Opcode>(it.Next()); 863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(opcode == Translation::STACK_SLOT || 864257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch opcode == Translation::LITERAL); 865257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int index = it.Next(); 866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the correct receiver in the optimized frame. 868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* receiver = NULL; 869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (opcode == Translation::LITERAL) { 870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch receiver = data->LiteralArray()->get(index); 871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Positive index means the value is spilled to the locals 873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // area. Negative means it is stored in the incoming parameter 874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // area. 875257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (index >= 0) { 876257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch receiver = GetExpression(index); 877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Index -1 overlaps with last parameter, -n with the first parameter, 879257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // (-n - 1) with the receiver with n being the number of parameters 880257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // of the outermost, optimized frame. 881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int parameter_count = ComputeParametersCount(); 882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int parameter_index = index + parameter_count; 883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch receiver = (parameter_index == -1) 884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ? this->receiver() 885257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch : this->GetParameter(parameter_index); 886257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code = function->shared()->code(); 890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationOutputData* output_data = 891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationOutputData::cast(code->deoptimization_data()); 892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned entry = Deoptimizer::GetOutputInfo(output_data, 893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ast_id, 894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->shared()); 895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned pc_offset = 896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; 897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(pc_offset > 0); 898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FrameSummary summary(receiver, function, code, pc_offset, is_constructor); 900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frames->Add(summary); 9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch is_constructor = false; 9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) { 9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The next encountered JS_FRAME will be marked as a constructor call. 9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Skip(Translation::NumberOfOperandsFor(opcode)); 9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!is_constructor); 9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch is_constructor = true; 907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Skip over operands to advance to the next opcode. 909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Skip(Translation::NumberOfOperandsFor(opcode)); 910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 911b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!is_constructor); 913b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochDeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( 917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int* deopt_index) { 918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(is_optimized()); 919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 920b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* opt_function = JSFunction::cast(function()); 921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* code = opt_function->code(); 922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The code object may have been replaced by lazy deoptimization. Fall 924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // back to a slow search in this case to find the original optimized 925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code object. 926b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!code->contains(pc())) { 9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code = isolate()->inner_pointer_to_code_cache()-> 9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GcSafeFindCodeForInnerPointer(pc()); 929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(code != NULL); 931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 933b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); 934b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch *deopt_index = safepoint_entry.deoptimization_index(); 9351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); 936b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 937b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return DeoptimizationInputData::cast(code->deoptimization_data()); 938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 940b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint OptimizedFrame::GetInlineCount() { 9423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(is_optimized()); 9433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int deopt_index = Safepoint::kNoDeoptimizationIndex; 9453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 9463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch TranslationIterator it(data->TranslationByteArray(), 9483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch data->TranslationIndex(deopt_index)->value()); 9493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 9503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(opcode == Translation::BEGIN); 9513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch USE(opcode); 9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Next(); // Drop frame count. 9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count = it.Next(); 9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return jsframe_count; 9553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 9563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid OptimizedFrame::GetFunctions(List<JSFunction*>* functions) { 959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(functions->length() == 0); 960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(is_optimized()); 961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int deopt_index = Safepoint::kNoDeoptimizationIndex; 963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 964b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TranslationIterator it(data->TranslationByteArray(), 966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->TranslationIndex(deopt_index)->value()); 967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(opcode == Translation::BEGIN); 9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch it.Next(); // Drop frame count. 9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count = it.Next(); 971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We insert the frames in reverse order because the frames 973b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // in the deoptimization translation are ordered bottom-to-top. 9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (jsframe_count > 0) { 975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch opcode = static_cast<Translation::Opcode>(it.Next()); 9763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (opcode == Translation::JS_FRAME) { 9773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jsframe_count--; 978b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Next(); // Skip ast id. 979b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int function_id = it.Next(); 980b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Next(); // Skip height. 981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function = 982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction::cast(data->LiteralArray()->get(function_id)); 983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch functions->Add(function); 984b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Skip over operands to advance to the next opcode. 986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Skip(Translation::NumberOfOperandsFor(opcode)); 987b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 988b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 991b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { 9933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Smi::cast(GetExpression(0))->value(); 9943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 9953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 99780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenAddress ArgumentsAdaptorFrame::GetCallerStackPointer() const { 9988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return fp() + StandardFrameConstants::kCallerSPOffset; 99980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 100080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 100180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 100280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenAddress InternalFrame::GetCallerStackPointer() const { 100380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Internal frames have no arguments. The stack pointer of the 100480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // caller is at a fixed offset from the frame pointer. 100580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return fp() + StandardFrameConstants::kCallerSPOffset; 100680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 100780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 100880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1009756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* ArgumentsAdaptorFrame::unchecked_code() const { 10108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return isolate()->builtins()->builtin( 101144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kArgumentsAdaptorTrampoline); 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1015756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain MerrickCode* InternalFrame::unchecked_code() const { 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int offset = InternalFrameConstants::kCodeOffset; 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* code = Memory::Object_at(fp() + offset); 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(code != NULL); 1019756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return reinterpret_cast<Code*>(code); 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackFrame::PrintIndex(StringStream* accumulator, 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) { 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid JavaScriptFrame::Print(StringStream* accumulator, 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const { 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* receiver = this->receiver(); 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* function = this->function(); 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->PrintSecurityTokenIfChanged(function); 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintIndex(accumulator, mode, index); 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* code = NULL; 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsConstructor()) accumulator->Add("new "); 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->PrintFunction(function, receiver, &code); 10426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get scope information for nicer output, if possible. If code is NULL, or 10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // doesn't contain scope info, scope_info will return 0 for the number of 10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // parameters, stack local variables, context local variables, stack slots, 10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // or context slots. 10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ScopeInfo> scope_info(ScopeInfo::Empty()); 10483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 10496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (function->IsJSFunction()) { 10506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared()); 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope_info = Handle<ScopeInfo>(shared->scope_info()); 10526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Object* script_obj = shared->script(); 10536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (script_obj->IsScript()) { 10546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Script> script(Script::cast(script_obj)); 10556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block accumulator->Add(" ["); 10566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block accumulator->PrintName(script->name()); 10576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 10586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Address pc = this->pc(); 10596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (code != NULL && code->kind() == Code::FUNCTION && 1060ac95265630a4e0c317a7a7201d17a57df7d9bcceLeon Clarke pc >= code->instruction_start() && pc < code->instruction_end()) { 10616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int source_pos = code->SourcePosition(pc); 10626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line = GetScriptLineNumberSafe(script, source_pos) + 1; 10636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block accumulator->Add(":%d", line); 10646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 10656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int function_start_pos = shared->start_position(); 10666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line = GetScriptLineNumberSafe(script, function_start_pos) + 1; 10676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block accumulator->Add(":~%d", line); 10686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 10696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 10706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block accumulator->Add("] "); 10716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 10726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 10736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("(this=%o", receiver); 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print the parameters. 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int parameters_count = ComputeParametersCount(); 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < parameters_count; i++) { 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(","); 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we have a name for the parameter we print it. Nameless 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameters are either because we have more actual parameters 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // than formal parameters or because we have no scope information. 10833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (i < scope_info->ParameterCount()) { 10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accumulator->PrintName(scope_info->ParameterName(i)); 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("="); 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("%o", GetParameter(i)); 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(")"); 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (mode == OVERVIEW) { 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("\n"); 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1095257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (is_optimized()) { 1096257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch accumulator->Add(" {\n// optimized frame\n}\n"); 1097257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return; 1098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" {\n"); 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the number of locals and expression stack elements. 11023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int stack_locals_count = scope_info->StackLocalCount(); 11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int heap_locals_count = scope_info->ContextLocalCount(); 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int expressions_count = ComputeExpressionsCount(); 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print stack-allocated local variables. 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stack_locals_count > 0) { 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" // stack-allocated locals\n"); 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < stack_locals_count; i++) { 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" var "); 11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accumulator->PrintName(scope_info->StackLocalName(i)); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" = "); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i < expressions_count) { 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("%o", GetExpression(i)); 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("// no expression found - inconsistent frame?"); 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("\n"); 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Try to get hold of the context of this frame. 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context* context = NULL; 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (this->context() != NULL && this->context()->IsContext()) { 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context = Context::cast(this->context()); 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print heap-allocated local variables. 11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (heap_locals_count > 0) { 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" // heap-allocated locals\n"); 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < heap_locals_count; i++) { 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" var "); 11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accumulator->PrintName(scope_info->ContextLocalName(i)); 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" = "); 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (context != NULL) { 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i < context->length()) { 11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch accumulator->Add("%o", context->get(Context::MIN_CONTEXT_SLOTS + i)); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add( 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "// warning: missing context slot - inconsistent frame?"); 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("// warning: no context found - inconsistent frame?"); 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("\n"); 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print the expression stack. 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int expressions_start = stack_locals_count; 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expressions_start < expressions_count) { 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" // expression stack (top to bottom)\n"); 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = expressions_count - 1; i >= expressions_start; i--) { 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsExpressionInsideHandler(i)) continue; 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" [%02d] : %o\n", i, GetExpression(i)); 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print details about the function. 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SharedFunctionInfo* shared = JSFunction::cast(function)->shared(); 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("--------- s o u r c e c o d e ---------\n"); 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shared->SourceCodePrint(accumulator, FLAG_max_stack_trace_source_length); 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("\n-----------------------------------------\n"); 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("}\n\n"); 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ArgumentsAdaptorFrame::Print(StringStream* accumulator, 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintMode mode, 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index) const { 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int actual = ComputeParametersCount(); 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int expected = -1; 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* function = this->function(); 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (function->IsJSFunction()) { 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected = JSFunction::cast(function)->shared()->formal_parameter_count(); 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintIndex(accumulator, mode, index); 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("arguments adaptor frame: %d->%d", actual, expected); 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (mode == OVERVIEW) { 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("\n"); 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" {\n"); 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Print actual arguments. 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (actual > 0) accumulator->Add(" // actual arguments\n"); 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < actual; i++) { 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" [%02d] : %o", i, GetParameter(i)); 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expected != -1 && i >= expected) { 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add(" // not passed to callee"); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("\n"); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block accumulator->Add("}\n\n"); 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid EntryFrame::Iterate(ObjectVisitor* v) const { 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandlerIterator it(this, top_handler()); 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!it.done()); 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler = it.handler(); 12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(handler->is_js_entry()); 12088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch handler->Iterate(v, LookupCode()); 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 121080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Make sure that the entry frame does not contain more than one 121180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // stack handler. 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it.Advance(); 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(it.done()); 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 12158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch IteratePc(v, pc_address(), LookupCode()); 1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StandardFrame::IterateExpressions(ObjectVisitor* v) const { 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int offset = StandardFrameConstants::kContextOffset; 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** base = &Memory::Object_at(sp()); 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** limit = &Memory::Object_at(fp() + offset) + 1; 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackHandler* handler = it.handler(); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Traverse pointers down to - but not including - the next 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler in the handler chain. Update the base to skip the 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler and allow the handler to traverse its own pointers. 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Address address = handler->address(); 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v->VisitPointers(base, reinterpret_cast<Object**>(address)); 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize); 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Traverse the pointers in the handler itself. 12328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch handler->Iterate(v, LookupCode()); 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v->VisitPointers(base, limit); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid JavaScriptFrame::Iterate(ObjectVisitor* v) const { 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IterateExpressions(v); 12408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch IteratePc(v, pc_address(), LookupCode()); 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid InternalFrame::Iterate(ObjectVisitor* v) const { 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Internal frames only have object pointers on the expression stack 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // as they never have any arguments. 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IterateExpressions(v); 12488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch IteratePc(v, pc_address(), LookupCode()); 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockJavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(n >= 0); 1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i <= n; i++) { 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (!iterator_.frame()->is_java_script()) iterator_.Advance(); 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (i == n) return JavaScriptFrame::cast(iterator_.frame()); 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block iterator_.Advance(); 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return NULL; 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------- 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) { 12713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MapWord map_word = object->map_word(); 12723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return map_word.IsForwardingAddress() ? 12733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map_word.ToForwardingAddress()->map() : map_word.ToMap(); 12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic int GcSafeSizeOfCodeSpaceObject(HeapObject* object) { 12783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object)); 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool GcSafeCodeContains(HeapObject* code, Address addr) { 12843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = GcSafeMapOfCodeSpaceObject(code); 12853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(map == code->GetHeap()->code_map()); 12863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address start = code->address(); 12873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address end = code->address() + code->SizeFromMap(map); 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return start <= addr && addr < end; 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCode* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object, 12943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address inner_pointer) { 129580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Code* code = reinterpret_cast<Code*>(object); 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(code != NULL && GcSafeCodeContains(code, inner_pointer)); 129780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return code; 129880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 129980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 130080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCode* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address inner_pointer) { 130344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap = isolate_->heap(); 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check if the inner pointer points into a large object chunk. 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); 13063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (large_page != NULL) { 13073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return GcSafeCastToCode(large_page->GetObject(), inner_pointer); 13083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Iterate through the page until we reach the end or find an object starting 13113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // after the inner pointer. 13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Page* page = Page::FromAddress(inner_pointer); 13133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address addr = page->skip_list()->StartFor(inner_pointer); 13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address top = heap->code_space()->top(); 13173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address limit = heap->code_space()->limit(); 13183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 131980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen while (true) { 13203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (addr == top && addr != limit) { 13213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch addr = limit; 13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 132380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapObject* obj = HeapObject::FromAddress(addr); 13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int obj_size = GcSafeSizeOfCodeSpaceObject(obj); 13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address next_addr = addr + obj_size; 13283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer); 13293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch addr = next_addr; 133080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 133180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 133280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 13343ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochInnerPointerToCodeCache::InnerPointerToCodeCacheEntry* 13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) { 133644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->counters()->pc_to_code()->Increment(); 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsPowerOf2(kInnerPointerToCodeCacheSize)); 133880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen uint32_t hash = ComputeIntegerHash( 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)), 1340c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch v8::internal::kZeroHashSeed); 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1); 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InnerPointerToCodeCacheEntry* entry = cache(index); 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry->inner_pointer == inner_pointer) { 134444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->counters()->pc_to_code_cached()->Increment(); 13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer)); 134680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 134780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Because this code may be interrupted by a profiling signal that 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // also queries the cache, we cannot update inner_pointer before the code 13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // has been set. Otherwise, we risk trying to use a cache entry before 135080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the code has been computed. 13513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch entry->code = GcSafeFindCodeForInnerPointer(inner_pointer); 1352b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->safepoint_entry.Reset(); 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch entry->inner_pointer = inner_pointer; 135480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 135580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return entry; 135680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 135780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 135880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 135980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// ------------------------------------------------------------------------- 136080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint NumRegs(RegList reglist) { 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int n = 0; 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (reglist != 0) { 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block n++; 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reglist &= reglist - 1; // clear one bit 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return n; 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstruct JSCallerSavedCodeData { 137244f0eee88ff00398ff7f715fab053374d808c90dSteve Block JSCallerSavedCodeData() { 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int i = 0; 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int r = 0; r < kNumRegs; r++) 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((kJSCallerSaved & (1 << r)) != 0) 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reg_code[i++] = r; 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(i == kNumJSCallerSaved); 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 138044f0eee88ff00398ff7f715fab053374d808c90dSteve Block int reg_code[kNumJSCallerSaved]; 138144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 138244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 138344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic LazyInstance<JSCallerSavedCodeData>::type caller_saved_code_data = 13853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LAZY_INSTANCE_INITIALIZER; 138644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 138744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint JSCallerSavedCode(int n) { 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(0 <= n && n < kNumJSCallerSaved); 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return caller_saved_code_data.Get().reg_code[n]; 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define DEFINE_WRAPPER(type, field) \ 13946ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass field##_Wrapper : public ZoneObject { \ 13956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public: /* NOLINT */ \ 13966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block field##_Wrapper(const field& original) : frame_(original) { \ 13976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } \ 13986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block field frame_; \ 13996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}; 14006ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockSTACK_FRAME_TYPE_LIST(DEFINE_WRAPPER) 14016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#undef DEFINE_WRAPPER 14026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14036ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic StackFrame* AllocateFrameCopy(StackFrame* frame) { 14046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define FRAME_TYPE_CASE(type, field) \ 14056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block case StackFrame::type: { \ 14066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block field##_Wrapper* wrapper = \ 14076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block new field##_Wrapper(*(reinterpret_cast<field*>(frame))); \ 14086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return &wrapper->frame_; \ 14096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 14106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block switch (frame->type()) { 14126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) 14136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block default: UNREACHABLE(); 14146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 14156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#undef FRAME_TYPE_CASE 14166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return NULL; 14176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 14186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14196ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockVector<StackFrame*> CreateStackMap() { 14206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ZoneList<StackFrame*> list(10); 14216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block for (StackFrameIterator it; !it.done(); it.Advance()) { 14226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block StackFrame* frame = AllocateFrameCopy(it.frame()); 14236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block list.Add(frame); 14246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 14256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return list.ToVector(); 14266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 14276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1430