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 | |
23 ReturnAddressLocationResolver | 22 ReturnAddressLocationResolver |
24 StackFrame::return_address_location_resolver_ = NULL; | 23 StackFrame::return_address_location_resolver_ = NULL; |
25 | 24 |
26 | 25 |
27 // Iterator that supports traversing the stack handlers of a | 26 // Iterator that supports traversing the stack handlers of a |
28 // particular frame. Needs to know the top of the handler chain. | 27 // particular frame. Needs to know the top of the handler chain. |
29 class StackHandlerIterator BASE_EMBEDDED { | 28 class StackHandlerIterator BASE_EMBEDDED { |
30 public: | 29 public: |
31 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) | 30 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) |
32 : limit_(frame->fp()), handler_(handler) { | 31 : limit_(frame->fp()), handler_(handler) { |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 void StackFrame::SetReturnAddressLocationResolver( | 399 void StackFrame::SetReturnAddressLocationResolver( |
401 ReturnAddressLocationResolver resolver) { | 400 ReturnAddressLocationResolver resolver) { |
402 DCHECK(return_address_location_resolver_ == NULL); | 401 DCHECK(return_address_location_resolver_ == NULL); |
403 return_address_location_resolver_ = resolver; | 402 return_address_location_resolver_ = resolver; |
404 } | 403 } |
405 | 404 |
406 | 405 |
407 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, | 406 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
408 State* state) { | 407 State* state) { |
409 DCHECK(state->fp != NULL); | 408 DCHECK(state->fp != NULL); |
410 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { | 409 |
411 return ARGUMENTS_ADAPTOR; | 410 if (!iterator->can_access_heap_objects_) { |
| 411 // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really |
| 412 // means that we are being called from the profiler, which can interrupt |
| 413 // the VM with a signal at any arbitrary instruction, with essentially |
| 414 // anything on the stack. So basically none of these checks are 100% |
| 415 // reliable. |
| 416 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
| 417 // An adapter frame has a special SMI constant for the context and |
| 418 // is not distinguished through the marker. |
| 419 return ARGUMENTS_ADAPTOR; |
| 420 } |
| 421 Object* marker = |
| 422 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
| 423 if (marker->IsSmi()) { |
| 424 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
| 425 } else { |
| 426 return JAVA_SCRIPT; |
| 427 } |
412 } | 428 } |
413 // The marker and function offsets overlap. If the marker isn't a | 429 |
414 // smi then the frame is a JavaScript frame -- and the marker is | 430 // Look up the code object to figure out the type of the stack frame. |
415 // really the function. | 431 Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address)); |
416 const int offset = StandardFrameConstants::kMarkerOffset; | 432 |
417 Object* marker = Memory::Object_at(state->fp + offset); | 433 Object* marker = |
418 if (!marker->IsSmi()) { | 434 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset); |
419 // If we're using a "safe" stack iterator, we treat optimized | 435 if (code_obj != nullptr) { |
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()) { | 436 switch (code_obj->kind()) { |
427 case Code::FUNCTION: | 437 case Code::FUNCTION: |
428 return JAVA_SCRIPT; | 438 return JAVA_SCRIPT; |
429 | |
430 case Code::HANDLER: | |
431 #ifdef DEBUG | |
432 if (!code_obj->is_hydrogen_stub()) { | |
433 // There's currently no support for non-hydrogen stub handlers. If | |
434 // you this, you'll have to implement it yourself. | |
435 UNREACHABLE(); | |
436 } | |
437 #endif | |
438 case Code::OPTIMIZED_FUNCTION: | 439 case Code::OPTIMIZED_FUNCTION: |
439 return OPTIMIZED; | 440 return OPTIMIZED; |
440 | 441 case Code::HANDLER: |
| 442 if (!marker->IsSmi()) { |
| 443 // Only hydrogen code stub handlers can have a non-SMI marker. |
| 444 DCHECK(code_obj->is_hydrogen_stub()); |
| 445 return OPTIMIZED; |
| 446 } |
| 447 break; // Marker encodes the frame type. |
441 default: | 448 default: |
442 UNREACHABLE(); | 449 break; // Marker encodes the frame type. |
443 return JAVA_SCRIPT; | |
444 } | 450 } |
445 } | 451 } |
| 452 |
| 453 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
| 454 // An adapter frame has a special SMI constant for the context and |
| 455 // is not distinguished through the marker. |
| 456 return ARGUMENTS_ADAPTOR; |
| 457 } |
| 458 |
| 459 // Didn't find a code object, or the code kind wasn't specific enough. |
| 460 // The marker should encode the frame type. |
446 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); | 461 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); |
447 } | 462 } |
448 | 463 |
449 | 464 |
450 #ifdef DEBUG | 465 #ifdef DEBUG |
451 bool StackFrame::can_access_heap_objects() const { | 466 bool StackFrame::can_access_heap_objects() const { |
452 return iterator_->can_access_heap_objects_; | 467 return iterator_->can_access_heap_objects_; |
453 } | 468 } |
454 #endif | 469 #endif |
455 | 470 |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 Address inner_pointer) { | 1453 Address inner_pointer) { |
1439 Code* code = reinterpret_cast<Code*>(object); | 1454 Code* code = reinterpret_cast<Code*>(object); |
1440 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer)); | 1455 DCHECK(code != NULL && GcSafeCodeContains(code, inner_pointer)); |
1441 return code; | 1456 return code; |
1442 } | 1457 } |
1443 | 1458 |
1444 | 1459 |
1445 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( | 1460 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( |
1446 Address inner_pointer) { | 1461 Address inner_pointer) { |
1447 Heap* heap = isolate_->heap(); | 1462 Heap* heap = isolate_->heap(); |
| 1463 if (!heap->code_space()->Contains(inner_pointer) && |
| 1464 !heap->lo_space()->Contains(inner_pointer)) { |
| 1465 return nullptr; |
| 1466 } |
| 1467 |
1448 // Check if the inner pointer points into a large object chunk. | 1468 // Check if the inner pointer points into a large object chunk. |
1449 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); | 1469 LargePage* large_page = heap->lo_space()->FindPage(inner_pointer); |
1450 if (large_page != NULL) { | 1470 if (large_page != NULL) { |
1451 return GcSafeCastToCode(large_page->GetObject(), inner_pointer); | 1471 return GcSafeCastToCode(large_page->GetObject(), inner_pointer); |
1452 } | 1472 } |
1453 | 1473 |
1454 // Iterate through the page until we reach the end or find an object starting | 1474 // Iterate through the page until we reach the end or find an object starting |
1455 // after the inner pointer. | 1475 // after the inner pointer. |
1456 Page* page = Page::FromAddress(inner_pointer); | 1476 Page* page = Page::FromAddress(inner_pointer); |
1457 | 1477 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1583 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1564 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1584 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1565 list.Add(frame, zone); | 1585 list.Add(frame, zone); |
1566 } | 1586 } |
1567 return list.ToVector(); | 1587 return list.ToVector(); |
1568 } | 1588 } |
1569 | 1589 |
1570 | 1590 |
1571 } // namespace internal | 1591 } // namespace internal |
1572 } // namespace v8 | 1592 } // namespace v8 |
OLD | NEW |