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

Side by Side Diff: src/frames.cc

Issue 1350763004: StackFrameIterator looks up code object earlier to decide frame type. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « no previous file | src/heap/spaces.h » ('j') | src/heap/spaces.cc » ('J')
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/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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/heap/spaces.h » ('j') | src/heap/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698