OLD | NEW |
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/frames.h" | 5 #include "src/frames.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
11 #include "src/deoptimizer.h" | 11 #include "src/deoptimizer.h" |
12 #include "src/frames-inl.h" | 12 #include "src/frames-inl.h" |
13 #include "src/full-codegen/full-codegen.h" | 13 #include "src/full-codegen/full-codegen.h" |
14 #include "src/safepoint-table.h" | 14 #include "src/safepoint-table.h" |
15 #include "src/scopeinfo.h" | 15 #include "src/scopeinfo.h" |
16 #include "src/string-stream.h" | 16 #include "src/string-stream.h" |
17 #include "src/vm-state-inl.h" | 17 #include "src/vm-state-inl.h" |
18 | 18 |
19 namespace v8 { | 19 namespace v8 { |
20 namespace internal { | 20 namespace internal { |
21 | 21 |
| 22 #define TRACE(...) |
| 23 |
22 | 24 |
23 ReturnAddressLocationResolver | 25 ReturnAddressLocationResolver |
24 StackFrame::return_address_location_resolver_ = NULL; | 26 StackFrame::return_address_location_resolver_ = NULL; |
25 | 27 |
26 | 28 |
27 // Iterator that supports traversing the stack handlers of a | 29 // Iterator that supports traversing the stack handlers of a |
28 // particular frame. Needs to know the top of the handler chain. | 30 // particular frame. Needs to know the top of the handler chain. |
29 class StackHandlerIterator BASE_EMBEDDED { | 31 class StackHandlerIterator BASE_EMBEDDED { |
30 public: | 32 public: |
31 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) | 33 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 void StackFrame::SetReturnAddressLocationResolver( | 402 void StackFrame::SetReturnAddressLocationResolver( |
401 ReturnAddressLocationResolver resolver) { | 403 ReturnAddressLocationResolver resolver) { |
402 DCHECK(return_address_location_resolver_ == NULL); | 404 DCHECK(return_address_location_resolver_ == NULL); |
403 return_address_location_resolver_ = resolver; | 405 return_address_location_resolver_ = resolver; |
404 } | 406 } |
405 | 407 |
406 | 408 |
407 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, | 409 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
408 State* state) { | 410 State* state) { |
409 DCHECK(state->fp != NULL); | 411 DCHECK(state->fp != NULL); |
| 412 |
| 413 TRACE("StackFrame::ComputeType pc=%p context=%p, marker=%p ", |
| 414 reinterpret_cast<void*>(*(state->pc_address)), |
| 415 reinterpret_cast<void*>(Memory::Object_at( |
| 416 state->fp + StandardFrameConstants::kContextOffset)), |
| 417 reinterpret_cast<void*>(Memory::Object_at( |
| 418 state->fp + StandardFrameConstants::kMarkerOffset))); |
| 419 |
| 420 if (!iterator->can_access_heap_objects_) { |
| 421 TRACE("(safe iterator) "); |
| 422 // TODO(titzer): this is totally bogus. We're hunting around on random |
| 423 // stacks without a clue. But whatever. Profiling. |
| 424 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
| 425 // An adapter frame has a special SMI constant for the context and |
| 426 // is not distinguished through the marker. |
| 427 TRACE("ARGUMENTS_ADAPTOR\n"); |
| 428 return ARGUMENTS_ADAPTOR; |
| 429 } |
| 430 Object* marker = |
| 431 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
| 432 if (marker->IsSmi()) { |
| 433 TRACE("MARKER = %d\n", Smi::cast(marker)->value()); |
| 434 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
| 435 } else { |
| 436 TRACE("JAVA_SCRIPT\n"); |
| 437 return JAVA_SCRIPT; |
| 438 } |
| 439 } |
| 440 |
| 441 // Look up the code object to figure out the type of the stack frame. |
| 442 Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address)); |
| 443 |
| 444 Object* marker = |
| 445 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
| 446 if (code_obj) { |
| 447 TRACE("(code kind = %d) ", static_cast<int>(code_obj->kind())); |
| 448 switch (code_obj->kind()) { |
| 449 case Code::FUNCTION: |
| 450 TRACE("JAVA_SCRIPT\n"); |
| 451 return JAVA_SCRIPT; |
| 452 case Code::OPTIMIZED_FUNCTION: |
| 453 TRACE("OPTIMIZED\n"); |
| 454 return OPTIMIZED; |
| 455 case Code::HANDLER: |
| 456 TRACE("(handler) \n"); |
| 457 if (!marker->IsSmi()) { |
| 458 // Only hydrogen code stub handlers can have a non-SMI marker. |
| 459 DCHECK(code_obj->is_hydrogen_stub()); |
| 460 return OPTIMIZED; |
| 461 } |
| 462 break; // Marker encodes the frame type. |
| 463 default: |
| 464 break; // Marker encodes the frame type. |
| 465 } |
| 466 } |
| 467 |
410 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { | 468 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
| 469 // An adapter frame has a special SMI constant for the context and |
| 470 // is not distinguished through the marker. |
| 471 TRACE("ARGUMENTS_ADAPTOR\n"); |
411 return ARGUMENTS_ADAPTOR; | 472 return ARGUMENTS_ADAPTOR; |
412 } | 473 } |
413 // The marker and function offsets overlap. If the marker isn't a | |
414 // smi then the frame is a JavaScript frame -- and the marker is | |
415 // really the function. | |
416 const int offset = StandardFrameConstants::kMarkerOffset; | |
417 Object* marker = Memory::Object_at(state->fp + offset); | |
418 if (!marker->IsSmi()) { | |
419 // If we're using a "safe" stack iterator, we treat optimized | |
420 // frames as normal JavaScript frames to avoid having to look | |
421 // into the heap to determine the state. This is safe as long | |
422 // as nobody tries to GC... | |
423 if (!iterator->can_access_heap_objects_) return JAVA_SCRIPT; | |
424 Code* code_obj = | |
425 GetContainingCode(iterator->isolate(), *(state->pc_address)); | |
426 switch (code_obj->kind()) { | |
427 case Code::FUNCTION: | |
428 return JAVA_SCRIPT; | |
429 | 474 |
430 case Code::HANDLER: | 475 // Didn't find a code object, or the code kind wasn't specific enough. |
431 #ifdef DEBUG | 476 // The marker should encode the frame type. |
432 if (!code_obj->is_hydrogen_stub()) { | 477 if (Smi::cast(marker)->value() > 100) { |
433 // There's currently no support for non-hydrogen stub handlers. If | 478 base::OS::DebugBreak(); |
434 // you this, you'll have to implement it yourself. | |
435 UNREACHABLE(); | |
436 } | |
437 #endif | |
438 case Code::OPTIMIZED_FUNCTION: | |
439 return OPTIMIZED; | |
440 | |
441 default: | |
442 UNREACHABLE(); | |
443 return JAVA_SCRIPT; | |
444 } | |
445 } | 479 } |
| 480 TRACE("MARKER = %d\n", Smi::cast(marker)->value()); |
446 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 481 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
447 } | 482 } |
448 | 483 |
449 | 484 |
450 #ifdef DEBUG | 485 #ifdef DEBUG |
451 bool StackFrame::can_access_heap_objects() const { | 486 bool StackFrame::can_access_heap_objects() const { |
452 return iterator_->can_access_heap_objects_; | 487 return iterator_->can_access_heap_objects_; |
453 } | 488 } |
454 #endif | 489 #endif |
455 | 490 |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 Address inner_pointer) { | 1473 Address inner_pointer) { |
1439 Code* code = reinterpret_cast<Code*>(object); | 1474 Code* code = reinterpret_cast<Code*>(object); |
1440 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer)); | 1475 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer)); |
1441 return code; | 1476 return code; |
1442 } | 1477 } |
1443 | 1478 |
1444 | 1479 |
1445 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( | 1480 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( |
1446 Address inner_pointer) { | 1481 Address inner_pointer) { |
1447 Heap* heap = isolate_->heap(); | 1482 Heap* heap = isolate_->heap(); |
| 1483 if (!heap->code_space()->Contains(inner_pointer) && |
| 1484 !heap->lo_space()->Contains(inner_pointer)) { |
| 1485 return nullptr; |
| 1486 } |
| 1487 |
1448 // Check if the inner pointer points into a large object chunk. | 1488 // Check if the inner pointer points into a large object chunk. |
1449 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); | 1489 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); |
1450 if (large_page != NULL) { | 1490 if (large_page != NULL) { |
1451 return GcSafeCastToCode(large_page->GetObject(), inner_pointer); | 1491 return GcSafeCastToCode(large_page->GetObject(), inner_pointer); |
1452 } | 1492 } |
1453 | 1493 |
1454 // Iterate through the page until we reach the end or find an object starting | 1494 // Iterate through the page until we reach the end or find an object starting |
1455 // after the inner pointer. | 1495 // after the inner pointer. |
1456 Page* page = Page::FromAddress(inner_pointer); | 1496 Page* page = Page::FromAddress(inner_pointer); |
1457 | 1497 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1603 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1564 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1604 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1565 list.Add(frame, zone); | 1605 list.Add(frame, zone); |
1566 } | 1606 } |
1567 return list.ToVector(); | 1607 return list.ToVector(); |
1568 } | 1608 } |
1569 | 1609 |
1570 | 1610 |
1571 } // namespace internal | 1611 } // namespace internal |
1572 } // namespace v8 | 1612 } // namespace v8 |
OLD | NEW |