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

Side by Side Diff: src/frames.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/frames-inl.h" 9 #include "src/frames-inl.h"
10 #include "src/full-codegen.h" 10 #include "src/full-codegen.h"
(...skipping 11 matching lines...) Expand all
22 StackFrame::return_address_location_resolver_ = NULL; 22 StackFrame::return_address_location_resolver_ = NULL;
23 23
24 24
25 // Iterator that supports traversing the stack handlers of a 25 // Iterator that supports traversing the stack handlers of a
26 // particular frame. Needs to know the top of the handler chain. 26 // particular frame. Needs to know the top of the handler chain.
27 class StackHandlerIterator BASE_EMBEDDED { 27 class StackHandlerIterator BASE_EMBEDDED {
28 public: 28 public:
29 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) 29 StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
30 : limit_(frame->fp()), handler_(handler) { 30 : limit_(frame->fp()), handler_(handler) {
31 // Make sure the handler has already been unwound to this frame. 31 // Make sure the handler has already been unwound to this frame.
32 ASSERT(frame->sp() <= handler->address()); 32 DCHECK(frame->sp() <= handler->address());
33 } 33 }
34 34
35 StackHandler* handler() const { return handler_; } 35 StackHandler* handler() const { return handler_; }
36 36
37 bool done() { 37 bool done() {
38 return handler_ == NULL || handler_->address() > limit_; 38 return handler_ == NULL || handler_->address() > limit_;
39 } 39 }
40 void Advance() { 40 void Advance() {
41 ASSERT(!done()); 41 DCHECK(!done());
42 handler_ = handler_->next(); 42 handler_ = handler_->next();
43 } 43 }
44 44
45 private: 45 private:
46 const Address limit_; 46 const Address limit_;
47 StackHandler* handler_; 47 StackHandler* handler_;
48 }; 48 };
49 49
50 50
51 // ------------------------------------------------------------------------- 51 // -------------------------------------------------------------------------
(...skipping 16 matching lines...) Expand all
68 } 68 }
69 69
70 70
71 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t) 71 StackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
72 : StackFrameIteratorBase(isolate, true) { 72 : StackFrameIteratorBase(isolate, true) {
73 Reset(t); 73 Reset(t);
74 } 74 }
75 75
76 76
77 void StackFrameIterator::Advance() { 77 void StackFrameIterator::Advance() {
78 ASSERT(!done()); 78 DCHECK(!done());
79 // Compute the state of the calling frame before restoring 79 // Compute the state of the calling frame before restoring
80 // callee-saved registers and unwinding handlers. This allows the 80 // callee-saved registers and unwinding handlers. This allows the
81 // frame code that computes the caller state to access the top 81 // frame code that computes the caller state to access the top
82 // handler and the value of any callee-saved register if needed. 82 // handler and the value of any callee-saved register if needed.
83 StackFrame::State state; 83 StackFrame::State state;
84 StackFrame::Type type = frame_->GetCallerState(&state); 84 StackFrame::Type type = frame_->GetCallerState(&state);
85 85
86 // Unwind handlers corresponding to the current frame. 86 // Unwind handlers corresponding to the current frame.
87 StackHandlerIterator it(frame_, handler_); 87 StackHandlerIterator it(frame_, handler_);
88 while (!it.done()) it.Advance(); 88 while (!it.done()) it.Advance();
89 handler_ = it.handler(); 89 handler_ = it.handler();
90 90
91 // Advance to the calling frame. 91 // Advance to the calling frame.
92 frame_ = SingletonFor(type, &state); 92 frame_ = SingletonFor(type, &state);
93 93
94 // When we're done iterating over the stack frames, the handler 94 // When we're done iterating over the stack frames, the handler
95 // chain must have been completely unwound. 95 // chain must have been completely unwound.
96 ASSERT(!done() || handler_ == NULL); 96 DCHECK(!done() || handler_ == NULL);
97 } 97 }
98 98
99 99
100 void StackFrameIterator::Reset(ThreadLocalTop* top) { 100 void StackFrameIterator::Reset(ThreadLocalTop* top) {
101 StackFrame::State state; 101 StackFrame::State state;
102 StackFrame::Type type = ExitFrame::GetStateForFramePointer( 102 StackFrame::Type type = ExitFrame::GetStateForFramePointer(
103 Isolate::c_entry_fp(top), &state); 103 Isolate::c_entry_fp(top), &state);
104 handler_ = StackHandler::FromAddress(Isolate::handler(top)); 104 handler_ = StackHandler::FromAddress(Isolate::handler(top));
105 if (SingletonFor(type) == NULL) return; 105 if (SingletonFor(type) == NULL) return;
106 frame_ = SingletonFor(type, &state); 106 frame_ = SingletonFor(type, &state);
107 } 107 }
108 108
109 109
110 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type, 110 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
111 StackFrame::State* state) { 111 StackFrame::State* state) {
112 if (type == StackFrame::NONE) return NULL; 112 if (type == StackFrame::NONE) return NULL;
113 StackFrame* result = SingletonFor(type); 113 StackFrame* result = SingletonFor(type);
114 ASSERT(result != NULL); 114 DCHECK(result != NULL);
115 result->state_ = *state; 115 result->state_ = *state;
116 return result; 116 return result;
117 } 117 }
118 118
119 119
120 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) { 120 StackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
121 #define FRAME_TYPE_CASE(type, field) \ 121 #define FRAME_TYPE_CASE(type, field) \
122 case StackFrame::type: result = &field##_; break; 122 case StackFrame::type: result = &field##_; break;
123 123
124 StackFrame* result = NULL; 124 StackFrame* result = NULL;
(...skipping 24 matching lines...) Expand all
149 void JavaScriptFrameIterator::Advance() { 149 void JavaScriptFrameIterator::Advance() {
150 do { 150 do {
151 iterator_.Advance(); 151 iterator_.Advance();
152 } while (!iterator_.done() && !iterator_.frame()->is_java_script()); 152 } while (!iterator_.done() && !iterator_.frame()->is_java_script());
153 } 153 }
154 154
155 155
156 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() { 156 void JavaScriptFrameIterator::AdvanceToArgumentsFrame() {
157 if (!frame()->has_adapted_arguments()) return; 157 if (!frame()->has_adapted_arguments()) return;
158 iterator_.Advance(); 158 iterator_.Advance();
159 ASSERT(iterator_.frame()->is_arguments_adaptor()); 159 DCHECK(iterator_.frame()->is_arguments_adaptor());
160 } 160 }
161 161
162 162
163 // ------------------------------------------------------------------------- 163 // -------------------------------------------------------------------------
164 164
165 165
166 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate) 166 StackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
167 : JavaScriptFrameIterator(isolate) { 167 : JavaScriptFrameIterator(isolate) {
168 if (!done() && !IsValidFrame()) Advance(); 168 if (!done() && !IsValidFrame()) Advance();
169 } 169 }
(...skipping 28 matching lines...) Expand all
198 high_bound_(js_entry_sp), 198 high_bound_(js_entry_sp),
199 top_frame_type_(StackFrame::NONE), 199 top_frame_type_(StackFrame::NONE),
200 external_callback_scope_(isolate->external_callback_scope()) { 200 external_callback_scope_(isolate->external_callback_scope()) {
201 StackFrame::State state; 201 StackFrame::State state;
202 StackFrame::Type type; 202 StackFrame::Type type;
203 ThreadLocalTop* top = isolate->thread_local_top(); 203 ThreadLocalTop* top = isolate->thread_local_top();
204 if (IsValidTop(top)) { 204 if (IsValidTop(top)) {
205 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); 205 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
206 top_frame_type_ = type; 206 top_frame_type_ = type;
207 } else if (IsValidStackAddress(fp)) { 207 } else if (IsValidStackAddress(fp)) {
208 ASSERT(fp != NULL); 208 DCHECK(fp != NULL);
209 state.fp = fp; 209 state.fp = fp;
210 state.sp = sp; 210 state.sp = sp;
211 state.pc_address = StackFrame::ResolveReturnAddressLocation( 211 state.pc_address = StackFrame::ResolveReturnAddressLocation(
212 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); 212 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
213 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, 213 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
214 // we check only that kMarkerOffset is within the stack bounds and do 214 // we check only that kMarkerOffset is within the stack bounds and do
215 // compile time check that kContextOffset slot is pushed on the stack before 215 // compile time check that kContextOffset slot is pushed on the stack before
216 // kMarkerOffset. 216 // kMarkerOffset.
217 STATIC_ASSERT(StandardFrameConstants::kMarkerOffset < 217 STATIC_ASSERT(StandardFrameConstants::kMarkerOffset <
218 StandardFrameConstants::kContextOffset); 218 StandardFrameConstants::kContextOffset);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 if (!IsValidExitFrame(c_entry_fp)) return false; 251 if (!IsValidExitFrame(c_entry_fp)) return false;
252 // There should be at least one JS_ENTRY stack handler. 252 // There should be at least one JS_ENTRY stack handler.
253 Address handler = Isolate::handler(top); 253 Address handler = Isolate::handler(top);
254 if (handler == NULL) return false; 254 if (handler == NULL) return false;
255 // Check that there are no js frames on top of the native frames. 255 // Check that there are no js frames on top of the native frames.
256 return c_entry_fp < handler; 256 return c_entry_fp < handler;
257 } 257 }
258 258
259 259
260 void SafeStackFrameIterator::AdvanceOneFrame() { 260 void SafeStackFrameIterator::AdvanceOneFrame() {
261 ASSERT(!done()); 261 DCHECK(!done());
262 StackFrame* last_frame = frame_; 262 StackFrame* last_frame = frame_;
263 Address last_sp = last_frame->sp(), last_fp = last_frame->fp(); 263 Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
264 // Before advancing to the next stack frame, perform pointer validity tests. 264 // Before advancing to the next stack frame, perform pointer validity tests.
265 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) { 265 if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
266 frame_ = NULL; 266 frame_ = NULL;
267 return; 267 return;
268 } 268 }
269 269
270 // Advance to the previous frame. 270 // Advance to the previous frame.
271 StackFrame::State state; 271 StackFrame::State state;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 // frame beneath it. There may be other EXIT frames on top of the 334 // frame beneath it. There may be other EXIT frames on top of the
335 // ExternalCallbackScope, just skip them as we cannot collect any useful 335 // ExternalCallbackScope, just skip them as we cannot collect any useful
336 // information about them. 336 // information about them.
337 if (external_callback_scope_->scope_address() < frame_->fp()) { 337 if (external_callback_scope_->scope_address() < frame_->fp()) {
338 Address* callback_address = 338 Address* callback_address =
339 external_callback_scope_->callback_address(); 339 external_callback_scope_->callback_address();
340 if (*callback_address != NULL) { 340 if (*callback_address != NULL) {
341 frame_->state_.pc_address = callback_address; 341 frame_->state_.pc_address = callback_address;
342 } 342 }
343 external_callback_scope_ = external_callback_scope_->previous(); 343 external_callback_scope_ = external_callback_scope_->previous();
344 ASSERT(external_callback_scope_ == NULL || 344 DCHECK(external_callback_scope_ == NULL ||
345 external_callback_scope_->scope_address() > frame_->fp()); 345 external_callback_scope_->scope_address() > frame_->fp());
346 return; 346 return;
347 } 347 }
348 } 348 }
349 } 349 }
350 } 350 }
351 351
352 352
353 // ------------------------------------------------------------------------- 353 // -------------------------------------------------------------------------
354 354
355 355
356 Code* StackFrame::GetSafepointData(Isolate* isolate, 356 Code* StackFrame::GetSafepointData(Isolate* isolate,
357 Address inner_pointer, 357 Address inner_pointer,
358 SafepointEntry* safepoint_entry, 358 SafepointEntry* safepoint_entry,
359 unsigned* stack_slots) { 359 unsigned* stack_slots) {
360 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = 360 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
361 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); 361 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
362 if (!entry->safepoint_entry.is_valid()) { 362 if (!entry->safepoint_entry.is_valid()) {
363 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); 363 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
364 ASSERT(entry->safepoint_entry.is_valid()); 364 DCHECK(entry->safepoint_entry.is_valid());
365 } else { 365 } else {
366 ASSERT(entry->safepoint_entry.Equals( 366 DCHECK(entry->safepoint_entry.Equals(
367 entry->code->GetSafepointEntry(inner_pointer))); 367 entry->code->GetSafepointEntry(inner_pointer)));
368 } 368 }
369 369
370 // Fill in the results and return the code. 370 // Fill in the results and return the code.
371 Code* code = entry->code; 371 Code* code = entry->code;
372 *safepoint_entry = entry->safepoint_entry; 372 *safepoint_entry = entry->safepoint_entry;
373 *stack_slots = code->stack_slots(); 373 *stack_slots = code->stack_slots();
374 return code; 374 return code;
375 } 375 }
376 376
377 377
378 bool StackFrame::HasHandler() const { 378 bool StackFrame::HasHandler() const {
379 StackHandlerIterator it(this, top_handler()); 379 StackHandlerIterator it(this, top_handler());
380 return !it.done(); 380 return !it.done();
381 } 381 }
382 382
383 383
384 #ifdef DEBUG 384 #ifdef DEBUG
385 static bool GcSafeCodeContains(HeapObject* object, Address addr); 385 static bool GcSafeCodeContains(HeapObject* object, Address addr);
386 #endif 386 #endif
387 387
388 388
389 void StackFrame::IteratePc(ObjectVisitor* v, 389 void StackFrame::IteratePc(ObjectVisitor* v,
390 Address* pc_address, 390 Address* pc_address,
391 Code* holder) { 391 Code* holder) {
392 Address pc = *pc_address; 392 Address pc = *pc_address;
393 ASSERT(GcSafeCodeContains(holder, pc)); 393 DCHECK(GcSafeCodeContains(holder, pc));
394 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); 394 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
395 Object* code = holder; 395 Object* code = holder;
396 v->VisitPointer(&code); 396 v->VisitPointer(&code);
397 if (code != holder) { 397 if (code != holder) {
398 holder = reinterpret_cast<Code*>(code); 398 holder = reinterpret_cast<Code*>(code);
399 pc = holder->instruction_start() + pc_offset; 399 pc = holder->instruction_start() + pc_offset;
400 *pc_address = pc; 400 *pc_address = pc;
401 } 401 }
402 } 402 }
403 403
404 404
405 void StackFrame::SetReturnAddressLocationResolver( 405 void StackFrame::SetReturnAddressLocationResolver(
406 ReturnAddressLocationResolver resolver) { 406 ReturnAddressLocationResolver resolver) {
407 ASSERT(return_address_location_resolver_ == NULL); 407 DCHECK(return_address_location_resolver_ == NULL);
408 return_address_location_resolver_ = resolver; 408 return_address_location_resolver_ = resolver;
409 } 409 }
410 410
411 411
412 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, 412 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
413 State* state) { 413 State* state) {
414 ASSERT(state->fp != NULL); 414 DCHECK(state->fp != NULL);
415 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 415 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
416 return ARGUMENTS_ADAPTOR; 416 return ARGUMENTS_ADAPTOR;
417 } 417 }
418 // The marker and function offsets overlap. If the marker isn't a 418 // The marker and function offsets overlap. If the marker isn't a
419 // smi then the frame is a JavaScript frame -- and the marker is 419 // smi then the frame is a JavaScript frame -- and the marker is
420 // really the function. 420 // really the function.
421 const int offset = StandardFrameConstants::kMarkerOffset; 421 const int offset = StandardFrameConstants::kMarkerOffset;
422 Object* marker = Memory::Object_at(state->fp + offset); 422 Object* marker = Memory::Object_at(state->fp + offset);
423 if (!marker->IsSmi()) { 423 if (!marker->IsSmi()) {
424 // If we're using a "safe" stack iterator, we treat optimized 424 // If we're using a "safe" stack iterator, we treat optimized
425 // frames as normal JavaScript frames to avoid having to look 425 // frames as normal JavaScript frames to avoid having to look
426 // into the heap to determine the state. This is safe as long 426 // into the heap to determine the state. This is safe as long
427 // as nobody tries to GC... 427 // as nobody tries to GC...
428 if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT; 428 if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT;
429 Code::Kind kind = GetContainingCode(iterator->isolate(), 429 Code::Kind kind = GetContainingCode(iterator->isolate(),
430 *(state->pc_address))->kind(); 430 *(state->pc_address))->kind();
431 ASSERT(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION); 431 DCHECK(kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION);
432 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT; 432 return (kind == Code::OPTIMIZED_FUNCTION) ? OPTIMIZED : JAVA_SCRIPT;
433 } 433 }
434 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 434 return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
435 } 435 }
436 436
437 437
438 #ifdef DEBUG 438 #ifdef DEBUG
439 bool StackFrame::can_access_heap_objects() const { 439 bool StackFrame::can_access_heap_objects() const {
440 return iterator_->can_access_heap_objects_; 440 return iterator_->can_access_heap_objects_;
441 } 441 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 532
533 Address ExitFrame::GetCallerStackPointer() const { 533 Address ExitFrame::GetCallerStackPointer() const {
534 return fp() + ExitFrameConstants::kCallerSPDisplacement; 534 return fp() + ExitFrameConstants::kCallerSPDisplacement;
535 } 535 }
536 536
537 537
538 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { 538 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
539 if (fp == 0) return NONE; 539 if (fp == 0) return NONE;
540 Address sp = ComputeStackPointer(fp); 540 Address sp = ComputeStackPointer(fp);
541 FillState(fp, sp, state); 541 FillState(fp, sp, state);
542 ASSERT(*state->pc_address != NULL); 542 DCHECK(*state->pc_address != NULL);
543 return EXIT; 543 return EXIT;
544 } 544 }
545 545
546 546
547 Address ExitFrame::ComputeStackPointer(Address fp) { 547 Address ExitFrame::ComputeStackPointer(Address fp) {
548 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); 548 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset);
549 } 549 }
550 550
551 551
552 void ExitFrame::FillState(Address fp, Address sp, State* state) { 552 void ExitFrame::FillState(Address fp, Address sp, State* state) {
(...skipping 21 matching lines...) Expand all
574 const int offset = StandardFrameConstants::kExpressionsOffset; 574 const int offset = StandardFrameConstants::kExpressionsOffset;
575 return fp + offset - n * kPointerSize; 575 return fp + offset - n * kPointerSize;
576 } 576 }
577 577
578 578
579 int StandardFrame::ComputeExpressionsCount() const { 579 int StandardFrame::ComputeExpressionsCount() const {
580 const int offset = 580 const int offset =
581 StandardFrameConstants::kExpressionsOffset + kPointerSize; 581 StandardFrameConstants::kExpressionsOffset + kPointerSize;
582 Address base = fp() + offset; 582 Address base = fp() + offset;
583 Address limit = sp(); 583 Address limit = sp();
584 ASSERT(base >= limit); // stack grows downwards 584 DCHECK(base >= limit); // stack grows downwards
585 // Include register-allocated locals in number of expressions. 585 // Include register-allocated locals in number of expressions.
586 return static_cast<int>((base - limit) / kPointerSize); 586 return static_cast<int>((base - limit) / kPointerSize);
587 } 587 }
588 588
589 589
590 void StandardFrame::ComputeCallerState(State* state) const { 590 void StandardFrame::ComputeCallerState(State* state) const {
591 state->sp = caller_sp(); 591 state->sp = caller_sp();
592 state->fp = caller_fp(); 592 state->fp = caller_fp();
593 state->pc_address = ResolveReturnAddressLocation( 593 state->pc_address = ResolveReturnAddressLocation(
594 reinterpret_cast<Address*>(ComputePCAddress(fp()))); 594 reinterpret_cast<Address*>(ComputePCAddress(fp())));
(...skipping 13 matching lines...) Expand all
608 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 608 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
609 if (it.handler()->includes(address)) return true; 609 if (it.handler()->includes(address)) return true;
610 } 610 }
611 return false; 611 return false;
612 } 612 }
613 613
614 614
615 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 615 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
616 // Make sure that we're not doing "safe" stack frame iteration. We cannot 616 // Make sure that we're not doing "safe" stack frame iteration. We cannot
617 // possibly find pointers in optimized frames in that state. 617 // possibly find pointers in optimized frames in that state.
618 ASSERT(can_access_heap_objects()); 618 DCHECK(can_access_heap_objects());
619 619
620 // Compute the safepoint information. 620 // Compute the safepoint information.
621 unsigned stack_slots = 0; 621 unsigned stack_slots = 0;
622 SafepointEntry safepoint_entry; 622 SafepointEntry safepoint_entry;
623 Code* code = StackFrame::GetSafepointData( 623 Code* code = StackFrame::GetSafepointData(
624 isolate(), pc(), &safepoint_entry, &stack_slots); 624 isolate(), pc(), &safepoint_entry, &stack_slots);
625 unsigned slot_space = stack_slots * kPointerSize; 625 unsigned slot_space = stack_slots * kPointerSize;
626 626
627 // Visit the outgoing parameters. 627 // Visit the outgoing parameters.
628 Object** parameters_base = &Memory::Object_at(sp()); 628 Object** parameters_base = &Memory::Object_at(sp());
629 Object** parameters_limit = &Memory::Object_at( 629 Object** parameters_limit = &Memory::Object_at(
630 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space); 630 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
631 631
632 // Visit the parameters that may be on top of the saved registers. 632 // Visit the parameters that may be on top of the saved registers.
633 if (safepoint_entry.argument_count() > 0) { 633 if (safepoint_entry.argument_count() > 0) {
634 v->VisitPointers(parameters_base, 634 v->VisitPointers(parameters_base,
635 parameters_base + safepoint_entry.argument_count()); 635 parameters_base + safepoint_entry.argument_count());
636 parameters_base += safepoint_entry.argument_count(); 636 parameters_base += safepoint_entry.argument_count();
637 } 637 }
638 638
639 // Skip saved double registers. 639 // Skip saved double registers.
640 if (safepoint_entry.has_doubles()) { 640 if (safepoint_entry.has_doubles()) {
641 // Number of doubles not known at snapshot time. 641 // Number of doubles not known at snapshot time.
642 ASSERT(!isolate()->serializer_enabled()); 642 DCHECK(!isolate()->serializer_enabled());
643 parameters_base += DoubleRegister::NumAllocatableRegisters() * 643 parameters_base += DoubleRegister::NumAllocatableRegisters() *
644 kDoubleSize / kPointerSize; 644 kDoubleSize / kPointerSize;
645 } 645 }
646 646
647 // Visit the registers that contain pointers if any. 647 // Visit the registers that contain pointers if any.
648 if (safepoint_entry.HasRegisters()) { 648 if (safepoint_entry.HasRegisters()) {
649 for (int i = kNumSafepointRegisters - 1; i >=0; i--) { 649 for (int i = kNumSafepointRegisters - 1; i >=0; i--) {
650 if (safepoint_entry.HasRegisterAt(i)) { 650 if (safepoint_entry.HasRegisterAt(i)) {
651 int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i); 651 int reg_stack_index = MacroAssembler::SafepointRegisterStackIndex(i);
652 v->VisitPointer(parameters_base + reg_stack_index); 652 v->VisitPointer(parameters_base + reg_stack_index);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 701
702 int StubFrame::GetNumberOfIncomingArguments() const { 702 int StubFrame::GetNumberOfIncomingArguments() const {
703 return 0; 703 return 0;
704 } 704 }
705 705
706 706
707 void OptimizedFrame::Iterate(ObjectVisitor* v) const { 707 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
708 #ifdef DEBUG 708 #ifdef DEBUG
709 // Make sure that optimized frames do not contain any stack handlers. 709 // Make sure that optimized frames do not contain any stack handlers.
710 StackHandlerIterator it(this, top_handler()); 710 StackHandlerIterator it(this, top_handler());
711 ASSERT(it.done()); 711 DCHECK(it.done());
712 #endif 712 #endif
713 713
714 IterateCompiledFrame(v); 714 IterateCompiledFrame(v);
715 } 715 }
716 716
717 717
718 void JavaScriptFrame::SetParameterValue(int index, Object* value) const { 718 void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
719 Memory::Object_at(GetParameterSlot(index)) = value; 719 Memory::Object_at(GetParameterSlot(index)) = value;
720 } 720 }
721 721
(...skipping 17 matching lines...) Expand all
739 } 739 }
740 } 740 }
741 741
742 742
743 Code* JavaScriptFrame::unchecked_code() const { 743 Code* JavaScriptFrame::unchecked_code() const {
744 return function()->code(); 744 return function()->code();
745 } 745 }
746 746
747 747
748 int JavaScriptFrame::GetNumberOfIncomingArguments() const { 748 int JavaScriptFrame::GetNumberOfIncomingArguments() const {
749 ASSERT(can_access_heap_objects() && 749 DCHECK(can_access_heap_objects() &&
750 isolate()->heap()->gc_state() == Heap::NOT_IN_GC); 750 isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
751 751
752 return function()->shared()->formal_parameter_count(); 752 return function()->shared()->formal_parameter_count();
753 } 753 }
754 754
755 755
756 Address JavaScriptFrame::GetCallerStackPointer() const { 756 Address JavaScriptFrame::GetCallerStackPointer() const {
757 return fp() + StandardFrameConstants::kCallerSPOffset; 757 return fp() + StandardFrameConstants::kCallerSPOffset;
758 } 758 }
759 759
760 760
761 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) { 761 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) {
762 ASSERT(functions->length() == 0); 762 DCHECK(functions->length() == 0);
763 functions->Add(function()); 763 functions->Add(function());
764 } 764 }
765 765
766 766
767 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { 767 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) {
768 ASSERT(functions->length() == 0); 768 DCHECK(functions->length() == 0);
769 Code* code_pointer = LookupCode(); 769 Code* code_pointer = LookupCode();
770 int offset = static_cast<int>(pc() - code_pointer->address()); 770 int offset = static_cast<int>(pc() - code_pointer->address());
771 FrameSummary summary(receiver(), 771 FrameSummary summary(receiver(),
772 function(), 772 function(),
773 code_pointer, 773 code_pointer,
774 offset, 774 offset,
775 IsConstructor()); 775 IsConstructor());
776 functions->Add(summary); 776 functions->Add(summary);
777 } 777 }
778 778
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 break; 834 break;
835 } 835 }
836 it.Advance(); 836 it.Advance();
837 } 837 }
838 } 838 }
839 839
840 840
841 void JavaScriptFrame::SaveOperandStack(FixedArray* store, 841 void JavaScriptFrame::SaveOperandStack(FixedArray* store,
842 int* stack_handler_index) const { 842 int* stack_handler_index) const {
843 int operands_count = store->length(); 843 int operands_count = store->length();
844 ASSERT_LE(operands_count, ComputeOperandsCount()); 844 DCHECK_LE(operands_count, ComputeOperandsCount());
845 845
846 // Visit the stack in LIFO order, saving operands and stack handlers into the 846 // Visit the stack in LIFO order, saving operands and stack handlers into the
847 // array. The saved stack handlers store a link to the next stack handler, 847 // array. The saved stack handlers store a link to the next stack handler,
848 // which will allow RestoreOperandStack to rewind the handlers. 848 // which will allow RestoreOperandStack to rewind the handlers.
849 StackHandlerIterator it(this, top_handler()); 849 StackHandlerIterator it(this, top_handler());
850 int i = operands_count - 1; 850 int i = operands_count - 1;
851 *stack_handler_index = -1; 851 *stack_handler_index = -1;
852 for (; !it.done(); it.Advance()) { 852 for (; !it.done(); it.Advance()) {
853 StackHandler* handler = it.handler(); 853 StackHandler* handler = it.handler();
854 // Save operands pushed after the handler was pushed. 854 // Save operands pushed after the handler was pushed.
855 for (; GetOperandSlot(i) < handler->address(); i--) { 855 for (; GetOperandSlot(i) < handler->address(); i--) {
856 store->set(i, GetOperand(i)); 856 store->set(i, GetOperand(i));
857 } 857 }
858 ASSERT_GE(i + 1, StackHandlerConstants::kSlotCount); 858 DCHECK_GE(i + 1, StackHandlerConstants::kSlotCount);
859 ASSERT_EQ(handler->address(), GetOperandSlot(i)); 859 DCHECK_EQ(handler->address(), GetOperandSlot(i));
860 int next_stack_handler_index = i + 1 - StackHandlerConstants::kSlotCount; 860 int next_stack_handler_index = i + 1 - StackHandlerConstants::kSlotCount;
861 handler->Unwind(isolate(), store, next_stack_handler_index, 861 handler->Unwind(isolate(), store, next_stack_handler_index,
862 *stack_handler_index); 862 *stack_handler_index);
863 *stack_handler_index = next_stack_handler_index; 863 *stack_handler_index = next_stack_handler_index;
864 i -= StackHandlerConstants::kSlotCount; 864 i -= StackHandlerConstants::kSlotCount;
865 } 865 }
866 866
867 // Save any remaining operands. 867 // Save any remaining operands.
868 for (; i >= 0; i--) { 868 for (; i >= 0; i--) {
869 store->set(i, GetOperand(i)); 869 store->set(i, GetOperand(i));
870 } 870 }
871 } 871 }
872 872
873 873
874 void JavaScriptFrame::RestoreOperandStack(FixedArray* store, 874 void JavaScriptFrame::RestoreOperandStack(FixedArray* store,
875 int stack_handler_index) { 875 int stack_handler_index) {
876 int operands_count = store->length(); 876 int operands_count = store->length();
877 ASSERT_LE(operands_count, ComputeOperandsCount()); 877 DCHECK_LE(operands_count, ComputeOperandsCount());
878 int i = 0; 878 int i = 0;
879 while (i <= stack_handler_index) { 879 while (i <= stack_handler_index) {
880 if (i < stack_handler_index) { 880 if (i < stack_handler_index) {
881 // An operand. 881 // An operand.
882 ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); 882 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
883 Memory::Object_at(GetOperandSlot(i)) = store->get(i); 883 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
884 i++; 884 i++;
885 } else { 885 } else {
886 // A stack handler. 886 // A stack handler.
887 ASSERT_EQ(i, stack_handler_index); 887 DCHECK_EQ(i, stack_handler_index);
888 // The FixedArray store grows up. The stack grows down. So the operand 888 // The FixedArray store grows up. The stack grows down. So the operand
889 // slot for i actually points to the bottom of the top word in the 889 // slot for i actually points to the bottom of the top word in the
890 // handler. The base of the StackHandler* is the address of the bottom 890 // handler. The base of the StackHandler* is the address of the bottom
891 // word, which will be the last slot that is in the handler. 891 // word, which will be the last slot that is in the handler.
892 int handler_slot_index = i + StackHandlerConstants::kSlotCount - 1; 892 int handler_slot_index = i + StackHandlerConstants::kSlotCount - 1;
893 StackHandler *handler = 893 StackHandler *handler =
894 StackHandler::FromAddress(GetOperandSlot(handler_slot_index)); 894 StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
895 stack_handler_index = handler->Rewind(isolate(), store, i, fp()); 895 stack_handler_index = handler->Rewind(isolate(), store, i, fp());
896 i += StackHandlerConstants::kSlotCount; 896 i += StackHandlerConstants::kSlotCount;
897 } 897 }
898 } 898 }
899 899
900 for (; i < operands_count; i++) { 900 for (; i < operands_count; i++) {
901 ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); 901 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
902 Memory::Object_at(GetOperandSlot(i)) = store->get(i); 902 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
903 } 903 }
904 } 904 }
905 905
906 906
907 void FrameSummary::Print() { 907 void FrameSummary::Print() {
908 PrintF("receiver: "); 908 PrintF("receiver: ");
909 receiver_->ShortPrint(); 909 receiver_->ShortPrint();
910 PrintF("\nfunction: "); 910 PrintF("\nfunction: ");
911 function_->shared()->DebugName()->ShortPrint(); 911 function_->shared()->DebugName()->ShortPrint();
912 PrintF("\ncode: "); 912 PrintF("\ncode: ");
913 code_->ShortPrint(); 913 code_->ShortPrint();
914 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); 914 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT");
915 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); 915 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT");
916 PrintF("\npc: %d\n", offset_); 916 PrintF("\npc: %d\n", offset_);
917 } 917 }
918 918
919 919
920 JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array, 920 JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array,
921 int literal_id) { 921 int literal_id) {
922 if (literal_id == Translation::kSelfLiteralId) { 922 if (literal_id == Translation::kSelfLiteralId) {
923 return function(); 923 return function();
924 } 924 }
925 925
926 return JSFunction::cast(literal_array->get(literal_id)); 926 return JSFunction::cast(literal_array->get(literal_id));
927 } 927 }
928 928
929 929
930 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { 930 void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
931 ASSERT(frames->length() == 0); 931 DCHECK(frames->length() == 0);
932 ASSERT(is_optimized()); 932 DCHECK(is_optimized());
933 933
934 // Delegate to JS frame in absence of inlining. 934 // Delegate to JS frame in absence of inlining.
935 // TODO(turbofan): Revisit once we support inlining. 935 // TODO(turbofan): Revisit once we support inlining.
936 if (LookupCode()->is_turbofanned()) { 936 if (LookupCode()->is_turbofanned()) {
937 return JavaScriptFrame::Summarize(frames); 937 return JavaScriptFrame::Summarize(frames);
938 } 938 }
939 939
940 int deopt_index = Safepoint::kNoDeoptimizationIndex; 940 int deopt_index = Safepoint::kNoDeoptimizationIndex;
941 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 941 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
942 FixedArray* literal_array = data->LiteralArray(); 942 FixedArray* literal_array = data->LiteralArray();
943 943
944 // BUG(3243555): Since we don't have a lazy-deopt registered at 944 // BUG(3243555): Since we don't have a lazy-deopt registered at
945 // throw-statements, we can't use the translation at the call-site of 945 // throw-statements, we can't use the translation at the call-site of
946 // throw. An entry with no deoptimization index indicates a call-site 946 // throw. An entry with no deoptimization index indicates a call-site
947 // without a lazy-deopt. As a consequence we are not allowed to inline 947 // without a lazy-deopt. As a consequence we are not allowed to inline
948 // functions containing throw. 948 // functions containing throw.
949 ASSERT(deopt_index != Safepoint::kNoDeoptimizationIndex); 949 DCHECK(deopt_index != Safepoint::kNoDeoptimizationIndex);
950 950
951 TranslationIterator it(data->TranslationByteArray(), 951 TranslationIterator it(data->TranslationByteArray(),
952 data->TranslationIndex(deopt_index)->value()); 952 data->TranslationIndex(deopt_index)->value());
953 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 953 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
954 ASSERT(opcode == Translation::BEGIN); 954 DCHECK(opcode == Translation::BEGIN);
955 it.Next(); // Drop frame count. 955 it.Next(); // Drop frame count.
956 int jsframe_count = it.Next(); 956 int jsframe_count = it.Next();
957 957
958 // We create the summary in reverse order because the frames 958 // We create the summary in reverse order because the frames
959 // in the deoptimization translation are ordered bottom-to-top. 959 // in the deoptimization translation are ordered bottom-to-top.
960 bool is_constructor = IsConstructor(); 960 bool is_constructor = IsConstructor();
961 int i = jsframe_count; 961 int i = jsframe_count;
962 while (i > 0) { 962 while (i > 0) {
963 opcode = static_cast<Translation::Opcode>(it.Next()); 963 opcode = static_cast<Translation::Opcode>(it.Next());
964 if (opcode == Translation::JS_FRAME) { 964 if (opcode == Translation::JS_FRAME) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 } 1004 }
1005 1005
1006 Code* code = function->shared()->code(); 1006 Code* code = function->shared()->code();
1007 DeoptimizationOutputData* output_data = 1007 DeoptimizationOutputData* output_data =
1008 DeoptimizationOutputData::cast(code->deoptimization_data()); 1008 DeoptimizationOutputData::cast(code->deoptimization_data());
1009 unsigned entry = Deoptimizer::GetOutputInfo(output_data, 1009 unsigned entry = Deoptimizer::GetOutputInfo(output_data,
1010 ast_id, 1010 ast_id,
1011 function->shared()); 1011 function->shared());
1012 unsigned pc_offset = 1012 unsigned pc_offset =
1013 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; 1013 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize;
1014 ASSERT(pc_offset > 0); 1014 DCHECK(pc_offset > 0);
1015 1015
1016 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); 1016 FrameSummary summary(receiver, function, code, pc_offset, is_constructor);
1017 frames->Add(summary); 1017 frames->Add(summary);
1018 is_constructor = false; 1018 is_constructor = false;
1019 } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) { 1019 } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) {
1020 // The next encountered JS_FRAME will be marked as a constructor call. 1020 // The next encountered JS_FRAME will be marked as a constructor call.
1021 it.Skip(Translation::NumberOfOperandsFor(opcode)); 1021 it.Skip(Translation::NumberOfOperandsFor(opcode));
1022 ASSERT(!is_constructor); 1022 DCHECK(!is_constructor);
1023 is_constructor = true; 1023 is_constructor = true;
1024 } else { 1024 } else {
1025 // Skip over operands to advance to the next opcode. 1025 // Skip over operands to advance to the next opcode.
1026 it.Skip(Translation::NumberOfOperandsFor(opcode)); 1026 it.Skip(Translation::NumberOfOperandsFor(opcode));
1027 } 1027 }
1028 } 1028 }
1029 ASSERT(!is_constructor); 1029 DCHECK(!is_constructor);
1030 } 1030 }
1031 1031
1032 1032
1033 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( 1033 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
1034 int* deopt_index) { 1034 int* deopt_index) {
1035 ASSERT(is_optimized()); 1035 DCHECK(is_optimized());
1036 1036
1037 JSFunction* opt_function = function(); 1037 JSFunction* opt_function = function();
1038 Code* code = opt_function->code(); 1038 Code* code = opt_function->code();
1039 1039
1040 // The code object may have been replaced by lazy deoptimization. Fall 1040 // The code object may have been replaced by lazy deoptimization. Fall
1041 // back to a slow search in this case to find the original optimized 1041 // back to a slow search in this case to find the original optimized
1042 // code object. 1042 // code object.
1043 if (!code->contains(pc())) { 1043 if (!code->contains(pc())) {
1044 code = isolate()->inner_pointer_to_code_cache()-> 1044 code = isolate()->inner_pointer_to_code_cache()->
1045 GcSafeFindCodeForInnerPointer(pc()); 1045 GcSafeFindCodeForInnerPointer(pc());
1046 } 1046 }
1047 ASSERT(code != NULL); 1047 DCHECK(code != NULL);
1048 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 1048 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
1049 1049
1050 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); 1050 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc());
1051 *deopt_index = safepoint_entry.deoptimization_index(); 1051 *deopt_index = safepoint_entry.deoptimization_index();
1052 ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); 1052 DCHECK(*deopt_index != Safepoint::kNoDeoptimizationIndex);
1053 1053
1054 return DeoptimizationInputData::cast(code->deoptimization_data()); 1054 return DeoptimizationInputData::cast(code->deoptimization_data());
1055 } 1055 }
1056 1056
1057 1057
1058 int OptimizedFrame::GetInlineCount() { 1058 int OptimizedFrame::GetInlineCount() {
1059 ASSERT(is_optimized()); 1059 DCHECK(is_optimized());
1060 1060
1061 // Delegate to JS frame in absence of inlining. 1061 // Delegate to JS frame in absence of inlining.
1062 // TODO(turbofan): Revisit once we support inlining. 1062 // TODO(turbofan): Revisit once we support inlining.
1063 if (LookupCode()->is_turbofanned()) { 1063 if (LookupCode()->is_turbofanned()) {
1064 return JavaScriptFrame::GetInlineCount(); 1064 return JavaScriptFrame::GetInlineCount();
1065 } 1065 }
1066 1066
1067 int deopt_index = Safepoint::kNoDeoptimizationIndex; 1067 int deopt_index = Safepoint::kNoDeoptimizationIndex;
1068 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 1068 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
1069 1069
1070 TranslationIterator it(data->TranslationByteArray(), 1070 TranslationIterator it(data->TranslationByteArray(),
1071 data->TranslationIndex(deopt_index)->value()); 1071 data->TranslationIndex(deopt_index)->value());
1072 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 1072 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1073 ASSERT(opcode == Translation::BEGIN); 1073 DCHECK(opcode == Translation::BEGIN);
1074 USE(opcode); 1074 USE(opcode);
1075 it.Next(); // Drop frame count. 1075 it.Next(); // Drop frame count.
1076 int jsframe_count = it.Next(); 1076 int jsframe_count = it.Next();
1077 return jsframe_count; 1077 return jsframe_count;
1078 } 1078 }
1079 1079
1080 1080
1081 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) { 1081 void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
1082 ASSERT(functions->length() == 0); 1082 DCHECK(functions->length() == 0);
1083 ASSERT(is_optimized()); 1083 DCHECK(is_optimized());
1084 1084
1085 // Delegate to JS frame in absence of inlining. 1085 // Delegate to JS frame in absence of inlining.
1086 // TODO(turbofan): Revisit once we support inlining. 1086 // TODO(turbofan): Revisit once we support inlining.
1087 if (LookupCode()->is_turbofanned()) { 1087 if (LookupCode()->is_turbofanned()) {
1088 return JavaScriptFrame::GetFunctions(functions); 1088 return JavaScriptFrame::GetFunctions(functions);
1089 } 1089 }
1090 1090
1091 int deopt_index = Safepoint::kNoDeoptimizationIndex; 1091 int deopt_index = Safepoint::kNoDeoptimizationIndex;
1092 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); 1092 DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
1093 FixedArray* literal_array = data->LiteralArray(); 1093 FixedArray* literal_array = data->LiteralArray();
1094 1094
1095 TranslationIterator it(data->TranslationByteArray(), 1095 TranslationIterator it(data->TranslationByteArray(),
1096 data->TranslationIndex(deopt_index)->value()); 1096 data->TranslationIndex(deopt_index)->value());
1097 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 1097 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1098 ASSERT(opcode == Translation::BEGIN); 1098 DCHECK(opcode == Translation::BEGIN);
1099 it.Next(); // Drop frame count. 1099 it.Next(); // Drop frame count.
1100 int jsframe_count = it.Next(); 1100 int jsframe_count = it.Next();
1101 1101
1102 // We insert the frames in reverse order because the frames 1102 // We insert the frames in reverse order because the frames
1103 // in the deoptimization translation are ordered bottom-to-top. 1103 // in the deoptimization translation are ordered bottom-to-top.
1104 while (jsframe_count > 0) { 1104 while (jsframe_count > 0) {
1105 opcode = static_cast<Translation::Opcode>(it.Next()); 1105 opcode = static_cast<Translation::Opcode>(it.Next());
1106 if (opcode == Translation::JS_FRAME) { 1106 if (opcode == Translation::JS_FRAME) {
1107 jsframe_count--; 1107 jsframe_count--;
1108 it.Next(); // Skip ast id. 1108 it.Next(); // Skip ast id.
(...skipping 27 matching lines...) Expand all
1136 1136
1137 Code* ArgumentsAdaptorFrame::unchecked_code() const { 1137 Code* ArgumentsAdaptorFrame::unchecked_code() const {
1138 return isolate()->builtins()->builtin( 1138 return isolate()->builtins()->builtin(
1139 Builtins::kArgumentsAdaptorTrampoline); 1139 Builtins::kArgumentsAdaptorTrampoline);
1140 } 1140 }
1141 1141
1142 1142
1143 Code* InternalFrame::unchecked_code() const { 1143 Code* InternalFrame::unchecked_code() const {
1144 const int offset = InternalFrameConstants::kCodeOffset; 1144 const int offset = InternalFrameConstants::kCodeOffset;
1145 Object* code = Memory::Object_at(fp() + offset); 1145 Object* code = Memory::Object_at(fp() + offset);
1146 ASSERT(code != NULL); 1146 DCHECK(code != NULL);
1147 return reinterpret_cast<Code*>(code); 1147 return reinterpret_cast<Code*>(code);
1148 } 1148 }
1149 1149
1150 1150
1151 void StackFrame::PrintIndex(StringStream* accumulator, 1151 void StackFrame::PrintIndex(StringStream* accumulator,
1152 PrintMode mode, 1152 PrintMode mode,
1153 int index) { 1153 int index) {
1154 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index); 1154 accumulator->Add((mode == OVERVIEW) ? "%5d: " : "[%d]: ", index);
1155 } 1155 }
1156 1156
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 accumulator->Add("\n"); 1243 accumulator->Add("\n");
1244 } 1244 }
1245 1245
1246 // Try to get hold of the context of this frame. 1246 // Try to get hold of the context of this frame.
1247 Context* context = NULL; 1247 Context* context = NULL;
1248 if (this->context() != NULL && this->context()->IsContext()) { 1248 if (this->context() != NULL && this->context()->IsContext()) {
1249 context = Context::cast(this->context()); 1249 context = Context::cast(this->context());
1250 } 1250 }
1251 while (context->IsWithContext()) { 1251 while (context->IsWithContext()) {
1252 context = context->previous(); 1252 context = context->previous();
1253 ASSERT(context != NULL); 1253 DCHECK(context != NULL);
1254 } 1254 }
1255 1255
1256 // Print heap-allocated local variables. 1256 // Print heap-allocated local variables.
1257 if (heap_locals_count > 0) { 1257 if (heap_locals_count > 0) {
1258 accumulator->Add(" // heap-allocated locals\n"); 1258 accumulator->Add(" // heap-allocated locals\n");
1259 } 1259 }
1260 for (int i = 0; i < heap_locals_count; i++) { 1260 for (int i = 0; i < heap_locals_count; i++) {
1261 accumulator->Add(" var "); 1261 accumulator->Add(" var ");
1262 accumulator->PrintName(scope_info->ContextLocalName(i)); 1262 accumulator->PrintName(scope_info->ContextLocalName(i));
1263 accumulator->Add(" = "); 1263 accumulator->Add(" = ");
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 } 1324 }
1325 accumulator->Add("\n"); 1325 accumulator->Add("\n");
1326 } 1326 }
1327 1327
1328 accumulator->Add("}\n\n"); 1328 accumulator->Add("}\n\n");
1329 } 1329 }
1330 1330
1331 1331
1332 void EntryFrame::Iterate(ObjectVisitor* v) const { 1332 void EntryFrame::Iterate(ObjectVisitor* v) const {
1333 StackHandlerIterator it(this, top_handler()); 1333 StackHandlerIterator it(this, top_handler());
1334 ASSERT(!it.done()); 1334 DCHECK(!it.done());
1335 StackHandler* handler = it.handler(); 1335 StackHandler* handler = it.handler();
1336 ASSERT(handler->is_js_entry()); 1336 DCHECK(handler->is_js_entry());
1337 handler->Iterate(v, LookupCode()); 1337 handler->Iterate(v, LookupCode());
1338 #ifdef DEBUG 1338 #ifdef DEBUG
1339 // Make sure that the entry frame does not contain more than one 1339 // Make sure that the entry frame does not contain more than one
1340 // stack handler. 1340 // stack handler.
1341 it.Advance(); 1341 it.Advance();
1342 ASSERT(it.done()); 1342 DCHECK(it.done());
1343 #endif 1343 #endif
1344 IteratePc(v, pc_address(), LookupCode()); 1344 IteratePc(v, pc_address(), LookupCode());
1345 } 1345 }
1346 1346
1347 1347
1348 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { 1348 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
1349 const int offset = StandardFrameConstants::kLastObjectOffset; 1349 const int offset = StandardFrameConstants::kLastObjectOffset;
1350 Object** base = &Memory::Object_at(sp()); 1350 Object** base = &Memory::Object_at(sp());
1351 Object** limit = &Memory::Object_at(fp() + offset) + 1; 1351 Object** limit = &Memory::Object_at(fp() + offset) + 1;
1352 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 1352 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 1412
1413 UNREACHABLE(); 1413 UNREACHABLE();
1414 return NULL; 1414 return NULL;
1415 } 1415 }
1416 1416
1417 1417
1418 // ------------------------------------------------------------------------- 1418 // -------------------------------------------------------------------------
1419 1419
1420 1420
1421 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { 1421 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
1422 ASSERT(n >= 0); 1422 DCHECK(n >= 0);
1423 for (int i = 0; i <= n; i++) { 1423 for (int i = 0; i <= n; i++) {
1424 while (!iterator_.frame()->is_java_script()) iterator_.Advance(); 1424 while (!iterator_.frame()->is_java_script()) iterator_.Advance();
1425 if (i == n) return JavaScriptFrame::cast(iterator_.frame()); 1425 if (i == n) return JavaScriptFrame::cast(iterator_.frame());
1426 iterator_.Advance(); 1426 iterator_.Advance();
1427 } 1427 }
1428 UNREACHABLE(); 1428 UNREACHABLE();
1429 return NULL; 1429 return NULL;
1430 } 1430 }
1431 1431
1432 1432
1433 // ------------------------------------------------------------------------- 1433 // -------------------------------------------------------------------------
1434 1434
1435 1435
1436 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) { 1436 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
1437 MapWord map_word = object->map_word(); 1437 MapWord map_word = object->map_word();
1438 return map_word.IsForwardingAddress() ? 1438 return map_word.IsForwardingAddress() ?
1439 map_word.ToForwardingAddress()->map() : map_word.ToMap(); 1439 map_word.ToForwardingAddress()->map() : map_word.ToMap();
1440 } 1440 }
1441 1441
1442 1442
1443 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) { 1443 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
1444 return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object)); 1444 return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
1445 } 1445 }
1446 1446
1447 1447
1448 #ifdef DEBUG 1448 #ifdef DEBUG
1449 static bool GcSafeCodeContains(HeapObject* code, Address addr) { 1449 static bool GcSafeCodeContains(HeapObject* code, Address addr) {
1450 Map* map = GcSafeMapOfCodeSpaceObject(code); 1450 Map* map = GcSafeMapOfCodeSpaceObject(code);
1451 ASSERT(map == code->GetHeap()->code_map()); 1451 DCHECK(map == code->GetHeap()->code_map());
1452 Address start = code->address(); 1452 Address start = code->address();
1453 Address end = code->address() + code->SizeFromMap(map); 1453 Address end = code->address() + code->SizeFromMap(map);
1454 return start <= addr && addr < end; 1454 return start <= addr && addr < end;
1455 } 1455 }
1456 #endif 1456 #endif
1457 1457
1458 1458
1459 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object, 1459 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
1460 Address inner_pointer) { 1460 Address inner_pointer) {
1461 Code* code = reinterpret_cast<Code*>(object); 1461 Code* code = reinterpret_cast<Code*>(object);
1462 ASSERT(code != NULL && GcSafeCodeContains(code, inner_pointer)); 1462 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer));
1463 return code; 1463 return code;
1464 } 1464 }
1465 1465
1466 1466
1467 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( 1467 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
1468 Address inner_pointer) { 1468 Address inner_pointer) {
1469 Heap* heap = isolate_->heap(); 1469 Heap* heap = isolate_->heap();
1470 // Check if the inner pointer points into a large object chunk. 1470 // Check if the inner pointer points into a large object chunk.
1471 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); 1471 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
1472 if (large_page != NULL) { 1472 if (large_page != NULL) {
(...skipping 20 matching lines...) Expand all
1493 Address next_addr = addr + obj_size; 1493 Address next_addr = addr + obj_size;
1494 if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer); 1494 if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
1495 addr = next_addr; 1495 addr = next_addr;
1496 } 1496 }
1497 } 1497 }
1498 1498
1499 1499
1500 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* 1500 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
1501 InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) { 1501 InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
1502 isolate_->counters()->pc_to_code()->Increment(); 1502 isolate_->counters()->pc_to_code()->Increment();
1503 ASSERT(IsPowerOf2(kInnerPointerToCodeCacheSize)); 1503 DCHECK(IsPowerOf2(kInnerPointerToCodeCacheSize));
1504 uint32_t hash = ComputeIntegerHash( 1504 uint32_t hash = ComputeIntegerHash(
1505 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)), 1505 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
1506 v8::internal::kZeroHashSeed); 1506 v8::internal::kZeroHashSeed);
1507 uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1); 1507 uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
1508 InnerPointerToCodeCacheEntry* entry = cache(index); 1508 InnerPointerToCodeCacheEntry* entry = cache(index);
1509 if (entry->inner_pointer == inner_pointer) { 1509 if (entry->inner_pointer == inner_pointer) {
1510 isolate_->counters()->pc_to_code_cached()->Increment(); 1510 isolate_->counters()->pc_to_code_cached()->Increment();
1511 ASSERT(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer)); 1511 DCHECK(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
1512 } else { 1512 } else {
1513 // Because this code may be interrupted by a profiling signal that 1513 // Because this code may be interrupted by a profiling signal that
1514 // also queries the cache, we cannot update inner_pointer before the code 1514 // also queries the cache, we cannot update inner_pointer before the code
1515 // has been set. Otherwise, we risk trying to use a cache entry before 1515 // has been set. Otherwise, we risk trying to use a cache entry before
1516 // the code has been computed. 1516 // the code has been computed.
1517 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer); 1517 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
1518 entry->safepoint_entry.Reset(); 1518 entry->safepoint_entry.Reset();
1519 entry->inner_pointer = inner_pointer; 1519 entry->inner_pointer = inner_pointer;
1520 } 1520 }
1521 return entry; 1521 return entry;
1522 } 1522 }
1523 1523
1524 1524
1525 // ------------------------------------------------------------------------- 1525 // -------------------------------------------------------------------------
1526 1526
1527 1527
1528 void StackHandler::Unwind(Isolate* isolate, 1528 void StackHandler::Unwind(Isolate* isolate,
1529 FixedArray* array, 1529 FixedArray* array,
1530 int offset, 1530 int offset,
1531 int previous_handler_offset) const { 1531 int previous_handler_offset) const {
1532 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5); 1532 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5);
1533 ASSERT_LE(0, offset); 1533 DCHECK_LE(0, offset);
1534 ASSERT_GE(array->length(), offset + StackHandlerConstants::kSlotCount); 1534 DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
1535 // Unwinding a stack handler into an array chains it in the opposite 1535 // Unwinding a stack handler into an array chains it in the opposite
1536 // direction, re-using the "next" slot as a "previous" link, so that stack 1536 // direction, re-using the "next" slot as a "previous" link, so that stack
1537 // handlers can be later re-wound in the correct order. Decode the "state" 1537 // handlers can be later re-wound in the correct order. Decode the "state"
1538 // slot into "index" and "kind" and store them separately, using the fp slot. 1538 // slot into "index" and "kind" and store them separately, using the fp slot.
1539 array->set(offset, Smi::FromInt(previous_handler_offset)); // next 1539 array->set(offset, Smi::FromInt(previous_handler_offset)); // next
1540 array->set(offset + 1, *code_address()); // code 1540 array->set(offset + 1, *code_address()); // code
1541 array->set(offset + 2, Smi::FromInt(static_cast<int>(index()))); // state 1541 array->set(offset + 2, Smi::FromInt(static_cast<int>(index()))); // state
1542 array->set(offset + 3, *context_address()); // context 1542 array->set(offset + 3, *context_address()); // context
1543 array->set(offset + 4, Smi::FromInt(static_cast<int>(kind()))); // fp 1543 array->set(offset + 4, Smi::FromInt(static_cast<int>(kind()))); // fp
1544 1544
1545 *isolate->handler_address() = next()->address(); 1545 *isolate->handler_address() = next()->address();
1546 } 1546 }
1547 1547
1548 1548
1549 int StackHandler::Rewind(Isolate* isolate, 1549 int StackHandler::Rewind(Isolate* isolate,
1550 FixedArray* array, 1550 FixedArray* array,
1551 int offset, 1551 int offset,
1552 Address fp) { 1552 Address fp) {
1553 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5); 1553 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 5);
1554 ASSERT_LE(0, offset); 1554 DCHECK_LE(0, offset);
1555 ASSERT_GE(array->length(), offset + StackHandlerConstants::kSlotCount); 1555 DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
1556 Smi* prev_handler_offset = Smi::cast(array->get(offset)); 1556 Smi* prev_handler_offset = Smi::cast(array->get(offset));
1557 Code* code = Code::cast(array->get(offset + 1)); 1557 Code* code = Code::cast(array->get(offset + 1));
1558 Smi* smi_index = Smi::cast(array->get(offset + 2)); 1558 Smi* smi_index = Smi::cast(array->get(offset + 2));
1559 Object* context = array->get(offset + 3); 1559 Object* context = array->get(offset + 3);
1560 Smi* smi_kind = Smi::cast(array->get(offset + 4)); 1560 Smi* smi_kind = Smi::cast(array->get(offset + 4));
1561 1561
1562 unsigned state = KindField::encode(static_cast<Kind>(smi_kind->value())) | 1562 unsigned state = KindField::encode(static_cast<Kind>(smi_kind->value())) |
1563 IndexField::encode(static_cast<unsigned>(smi_index->value())); 1563 IndexField::encode(static_cast<unsigned>(smi_index->value()));
1564 1564
1565 Memory::Address_at(address() + StackHandlerConstants::kNextOffset) = 1565 Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
(...skipping 22 matching lines...) Expand all
1588 }; 1588 };
1589 1589
1590 JSCallerSavedCodeData caller_saved_code_data; 1590 JSCallerSavedCodeData caller_saved_code_data;
1591 1591
1592 void SetUpJSCallerSavedCodeData() { 1592 void SetUpJSCallerSavedCodeData() {
1593 int i = 0; 1593 int i = 0;
1594 for (int r = 0; r < kNumRegs; r++) 1594 for (int r = 0; r < kNumRegs; r++)
1595 if ((kJSCallerSaved & (1 << r)) != 0) 1595 if ((kJSCallerSaved & (1 << r)) != 0)
1596 caller_saved_code_data.reg_code[i++] = r; 1596 caller_saved_code_data.reg_code[i++] = r;
1597 1597
1598 ASSERT(i == kNumJSCallerSaved); 1598 DCHECK(i == kNumJSCallerSaved);
1599 } 1599 }
1600 1600
1601 1601
1602 int JSCallerSavedCode(int n) { 1602 int JSCallerSavedCode(int n) {
1603 ASSERT(0 <= n && n < kNumJSCallerSaved); 1603 DCHECK(0 <= n && n < kNumJSCallerSaved);
1604 return caller_saved_code_data.reg_code[n]; 1604 return caller_saved_code_data.reg_code[n];
1605 } 1605 }
1606 1606
1607 1607
1608 #define DEFINE_WRAPPER(type, field) \ 1608 #define DEFINE_WRAPPER(type, field) \
1609 class field##_Wrapper : public ZoneObject { \ 1609 class field##_Wrapper : public ZoneObject { \
1610 public: /* NOLINT */ \ 1610 public: /* NOLINT */ \
1611 field##_Wrapper(const field& original) : frame_(original) { \ 1611 field##_Wrapper(const field& original) : frame_(original) { \
1612 } \ 1612 } \
1613 field frame_; \ 1613 field frame_; \
(...skipping 22 matching lines...) Expand all
1636 ZoneList<StackFrame*> list(10, zone); 1636 ZoneList<StackFrame*> list(10, zone);
1637 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1637 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1638 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1638 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1639 list.Add(frame, zone); 1639 list.Add(frame, zone);
1640 } 1640 }
1641 return list.ToVector(); 1641 return list.ToVector();
1642 } 1642 }
1643 1643
1644 1644
1645 } } // namespace v8::internal 1645 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698