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

Side by Side Diff: src/frames.cc

Issue 1696043002: [runtime] Unify and simplify how frames are marked (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tweaks Created 4 years, 10 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
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/ast.h" 9 #include "src/ast/ast.h"
10 #include "src/ast/scopeinfo.h" 10 #include "src/ast/scopeinfo.h"
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 } else if (IsValidStackAddress(fp)) { 209 } else if (IsValidStackAddress(fp)) {
210 DCHECK(fp != NULL); 210 DCHECK(fp != NULL);
211 state.fp = fp; 211 state.fp = fp;
212 state.sp = sp; 212 state.sp = sp;
213 state.pc_address = StackFrame::ResolveReturnAddressLocation( 213 state.pc_address = StackFrame::ResolveReturnAddressLocation(
214 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); 214 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
215 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, 215 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
216 // we check only that kMarkerOffset is within the stack bounds and do 216 // we check only that kMarkerOffset is within the stack bounds and do
217 // compile time check that kContextOffset slot is pushed on the stack before 217 // compile time check that kContextOffset slot is pushed on the stack before
218 // kMarkerOffset. 218 // kMarkerOffset.
219 STATIC_ASSERT(StandardFrameConstants::kMarkerOffset < 219 STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
220 StandardFrameConstants::kContextOffset); 220 StandardFrameConstants::kContextOffset);
221 Address frame_marker = fp + StandardFrameConstants::kMarkerOffset; 221 Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
222 if (IsValidStackAddress(frame_marker)) { 222 if (IsValidStackAddress(frame_marker)) {
223 type = StackFrame::ComputeType(this, &state); 223 type = StackFrame::ComputeType(this, &state);
224 top_frame_type_ = type; 224 top_frame_type_ = type;
225 } else { 225 } else {
226 // Mark the frame as JAVA_SCRIPT if we cannot determine its type. 226 // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
227 // The frame anyways will be skipped. 227 // The frame anyways will be skipped.
228 type = StackFrame::JAVA_SCRIPT; 228 type = StackFrame::JAVA_SCRIPT;
229 // Top frame is incomplete so we cannot reliably determine its type. 229 // Top frame is incomplete so we cannot reliably determine its type.
230 top_frame_type_ = StackFrame::NONE; 230 top_frame_type_ = StackFrame::NONE;
231 } 231 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 ReturnAddressLocationResolver resolver) { 401 ReturnAddressLocationResolver resolver) {
402 DCHECK(return_address_location_resolver_ == NULL); 402 DCHECK(return_address_location_resolver_ == NULL);
403 return_address_location_resolver_ = resolver; 403 return_address_location_resolver_ = resolver;
404 } 404 }
405 405
406 406
407 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, 407 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
408 State* state) { 408 State* state) {
409 DCHECK(state->fp != NULL); 409 DCHECK(state->fp != NULL);
410 410
411 Object* marker = Memory::Object_at(
412 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
413 if (marker->IsSmi()) {
414 StackFrame::Type candidate =
415 static_cast<StackFrame::Type>(Smi::cast(marker)->value());
416 switch (candidate) {
417 case ENTRY:
418 case ENTRY_CONSTRUCT:
419 case EXIT:
420 case STUB:
421 case STUB_FAILURE_TRAMPOLINE:
422 case INTERNAL:
423 case CONSTRUCT:
424 case ARGUMENTS_ADAPTOR:
425 return candidate;
426 case JAVA_SCRIPT:
427 case OPTIMIZED:
428 case INTERPRETED:
429 default:
430 // Unoptimized and optimized JavaScript frames, including interpreted
431 // frames, should never have a StackFrame::Type marker. If we find one,
432 // we're likely being called from the profiler in a bogus stack frame.
433 return NONE;
434 }
435 }
436
437 Object* maybe_function =
438 Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset);
411 if (!iterator->can_access_heap_objects_) { 439 if (!iterator->can_access_heap_objects_) {
412 // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really 440 // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
413 // means that we are being called from the profiler, which can interrupt 441 // means that we are being called from the profiler, which can interrupt
414 // the VM with a signal at any arbitrary instruction, with essentially 442 // the VM with a signal at any arbitrary instruction, with essentially
415 // anything on the stack. So basically none of these checks are 100% 443 // anything on the stack. So basically none of these checks are 100%
416 // reliable. 444 // reliable.
417 #if defined(USE_SIMULATOR) 445 #if defined(USE_SIMULATOR)
418 MSAN_MEMORY_IS_INITIALIZED( 446 MSAN_MEMORY_IS_INITIALIZED(
419 state->fp + StandardFrameConstants::kContextOffset, kPointerSize); 447 state->fp + StandardFrameConstants::kContextOffset, kPointerSize);
420 MSAN_MEMORY_IS_INITIALIZED( 448 MSAN_MEMORY_IS_INITIALIZED(
421 state->fp + StandardFrameConstants::kMarkerOffset, kPointerSize); 449 state->fp + StandardFrameConstants::kMarkerOffset, kPointerSize);
422 #endif 450 #endif
423 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 451 if (maybe_function->IsSmi()) {
424 // An adapter frame has a special SMI constant for the context and 452 return NONE;
425 // is not distinguished through the marker.
426 return ARGUMENTS_ADAPTOR;
427 }
428 Object* marker =
429 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
430 if (marker->IsSmi()) {
431 return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
432 } else { 453 } else {
433 return JAVA_SCRIPT; 454 return JAVA_SCRIPT;
434 } 455 }
435 } 456 }
436 457
437 // Look up the code object to figure out the type of the stack frame. 458 // Look up the code object to figure out the type of the stack frame.
438 Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address)); 459 Code* code_obj = GetContainingCode(iterator->isolate(), *(state->pc_address));
439
440 Object* marker =
441 Memory::Object_at(state->fp + StandardFrameConstants::kMarkerOffset);
442 if (code_obj != nullptr) { 460 if (code_obj != nullptr) {
443 switch (code_obj->kind()) { 461 switch (code_obj->kind()) {
444 case Code::FUNCTION: 462 case Code::FUNCTION:
445 return JAVA_SCRIPT; 463 return JAVA_SCRIPT;
446 case Code::OPTIMIZED_FUNCTION: 464 case Code::OPTIMIZED_FUNCTION:
447 return OPTIMIZED; 465 return OPTIMIZED;
448 case Code::WASM_FUNCTION: 466 case Code::WASM_FUNCTION:
449 return STUB; 467 return STUB;
450 case Code::BUILTIN: 468 case Code::BUILTIN:
451 if (!marker->IsSmi()) { 469 DCHECK(!maybe_function->IsSmi());
452 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 470 DCHECK(code_obj->is_interpreter_entry_trampoline() ||
453 // An adapter frame has a special SMI constant for the context and 471 code_obj->is_interpreter_enter_bytecode_dispatch());
454 // is not distinguished through the marker. 472 return INTERPRETED;
455 return ARGUMENTS_ADAPTOR;
456 } else {
457 // The interpreter entry trampoline has a non-SMI marker.
458 DCHECK(code_obj->is_interpreter_entry_trampoline() ||
459 code_obj->is_interpreter_enter_bytecode_dispatch());
460 return INTERPRETED;
461 }
462 }
463 break; // Marker encodes the frame type.
464 case Code::HANDLER:
465 if (!marker->IsSmi()) {
466 // Only hydrogen code stub handlers can have a non-SMI marker.
467 DCHECK(code_obj->is_hydrogen_stub());
468 return OPTIMIZED;
469 }
470 break; // Marker encodes the frame type.
471 default: 473 default:
472 break; // Marker encodes the frame type. 474 // All other types should have an explicit marker
475 UNREACHABLE();
476 break;
473 } 477 }
474 } 478 }
475 479
476 // Didn't find a code object, or the code kind wasn't specific enough. 480 return NONE;
477 // The marker should encode the frame type.
478 return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
479 } 481 }
480 482
481 483
482 #ifdef DEBUG 484 #ifdef DEBUG
483 bool StackFrame::can_access_heap_objects() const { 485 bool StackFrame::can_access_heap_objects() const {
484 return iterator_->can_access_heap_objects_; 486 return iterator_->can_access_heap_objects_;
485 } 487 }
486 #endif 488 #endif
487 489
488 490
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 643 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
642 // Make sure that we're not doing "safe" stack frame iteration. We cannot 644 // Make sure that we're not doing "safe" stack frame iteration. We cannot
643 // possibly find pointers in optimized frames in that state. 645 // possibly find pointers in optimized frames in that state.
644 DCHECK(can_access_heap_objects()); 646 DCHECK(can_access_heap_objects());
645 647
646 // Compute the safepoint information. 648 // Compute the safepoint information.
647 unsigned stack_slots = 0; 649 unsigned stack_slots = 0;
648 SafepointEntry safepoint_entry; 650 SafepointEntry safepoint_entry;
649 Code* code = StackFrame::GetSafepointData( 651 Code* code = StackFrame::GetSafepointData(
650 isolate(), pc(), &safepoint_entry, &stack_slots); 652 isolate(), pc(), &safepoint_entry, &stack_slots);
651 unsigned slot_space = 653 unsigned slot_space = stack_slots * kPointerSize;
652 stack_slots * kPointerSize - StandardFrameConstants::kFixedFrameSize;
653 654
654 // Visit the outgoing parameters. 655 // Visit the outgoing parameters.
Michael Starzinger 2016/02/23 10:57:33 nit: Comment is outdated.
danno 2016/03/07 09:33:38 Done.
656 int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
657 Object* marker = Memory::Object_at(fp() - kPointerSize);
658 if (marker->IsSmi()) {
659 StackFrame::Type candidate =
660 static_cast<StackFrame::Type>(Smi::cast(marker)->value());
661 switch (candidate) {
662 case ENTRY:
663 case ENTRY_CONSTRUCT:
664 case EXIT:
665 case STUB_FAILURE_TRAMPOLINE:
666 case ARGUMENTS_ADAPTOR:
667 case STUB:
668 case INTERNAL:
669 case CONSTRUCT:
670 frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
671 break;
672 case JAVA_SCRIPT:
673 case OPTIMIZED:
674 case INTERPRETED:
675 // These frame types have a context, but they are actually stored
676 // in the place on the stack that one finds the frame type.
677 UNREACHABLE();
678 break;
679 case NONE:
680 case NUMBER_OF_TYPES:
681 case MANUAL:
682 UNREACHABLE();
683 break;
684 }
685 }
686 slot_space -=
687 (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
688
689 Object** frame_header_base = &Memory::Object_at(fp() - frame_header_size);
690 Object** frame_header_limit = &Memory::Object_at(fp());
655 Object** parameters_base = &Memory::Object_at(sp()); 691 Object** parameters_base = &Memory::Object_at(sp());
656 Object** parameters_limit = &Memory::Object_at( 692 Object** parameters_limit = frame_header_base - slot_space / kPointerSize;
657 fp() + JavaScriptFrameConstants::kFunctionOffset - slot_space);
658 693
659 // Visit the parameters that may be on top of the saved registers. 694 // Visit the parameters that may be on top of the saved registers.
660 if (safepoint_entry.argument_count() > 0) { 695 if (safepoint_entry.argument_count() > 0) {
661 v->VisitPointers(parameters_base, 696 v->VisitPointers(parameters_base,
662 parameters_base + safepoint_entry.argument_count()); 697 parameters_base + safepoint_entry.argument_count());
663 parameters_base += safepoint_entry.argument_count(); 698 parameters_base += safepoint_entry.argument_count();
664 } 699 }
665 700
666 // Skip saved double registers. 701 // Skip saved double registers.
667 if (safepoint_entry.has_doubles()) { 702 if (safepoint_entry.has_doubles()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { 734 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) {
700 v->VisitPointer(parameters_limit + index); 735 v->VisitPointer(parameters_limit + index);
701 } 736 }
702 } 737 }
703 738
704 // Visit the return address in the callee and incoming arguments. 739 // Visit the return address in the callee and incoming arguments.
705 IteratePc(v, pc_address(), constant_pool_address(), code); 740 IteratePc(v, pc_address(), constant_pool_address(), code);
706 741
707 // Visit the context in stub frame and JavaScript frame. 742 // Visit the context in stub frame and JavaScript frame.
708 // Visit the function in JavaScript frame. 743 // Visit the function in JavaScript frame.
709 Object** fixed_base = &Memory::Object_at( 744 v->VisitPointers(frame_header_base, frame_header_limit);
710 fp() + StandardFrameConstants::kMarkerOffset);
711 Object** fixed_limit = &Memory::Object_at(fp());
712 v->VisitPointers(fixed_base, fixed_limit);
713 } 745 }
714 746
715 747
716 void StubFrame::Iterate(ObjectVisitor* v) const { 748 void StubFrame::Iterate(ObjectVisitor* v) const {
717 IterateCompiledFrame(v); 749 IterateCompiledFrame(v);
718 } 750 }
719 751
720 752
721 Code* StubFrame::unchecked_code() const { 753 Code* StubFrame::unchecked_code() const {
722 return static_cast<Code*>(isolate()->FindCodeObject(pc())); 754 return static_cast<Code*>(isolate()->FindCodeObject(pc()));
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 void InternalFrame::Iterate(ObjectVisitor* v) const { 1462 void InternalFrame::Iterate(ObjectVisitor* v) const {
1431 // Internal frames only have object pointers on the expression stack 1463 // Internal frames only have object pointers on the expression stack
1432 // as they never have any arguments. 1464 // as they never have any arguments.
1433 IterateExpressions(v); 1465 IterateExpressions(v);
1434 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 1466 IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
1435 } 1467 }
1436 1468
1437 1469
1438 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { 1470 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const {
1439 Object** base = &Memory::Object_at(sp()); 1471 Object** base = &Memory::Object_at(sp());
1440 Object** limit = &Memory::Object_at(fp() + 1472 Object** limit = &Memory::Object_at(
1441 kFirstRegisterParameterFrameOffset); 1473 fp() + StubFailureTrampolineFrameConstants::kFixedHeaderBottomOffset);
1442 v->VisitPointers(base, limit); 1474 v->VisitPointers(base, limit);
1443 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); 1475 base = &Memory::Object_at(fp() + StandardFrameConstants::kFunctionOffset);
1444 const int offset = StandardFrameConstants::kLastObjectOffset; 1476 const int offset = StandardFrameConstants::kLastObjectOffset;
1445 limit = &Memory::Object_at(fp() + offset) + 1; 1477 limit = &Memory::Object_at(fp() + offset) + 1;
1446 v->VisitPointers(base, limit); 1478 v->VisitPointers(base, limit);
1447 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); 1479 IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
1448 } 1480 }
1449 1481
1450 1482
1451 Address StubFailureTrampolineFrame::GetCallerStackPointer() const { 1483 Address StubFailureTrampolineFrame::GetCallerStackPointer() const {
1452 return fp() + StandardFrameConstants::kCallerSPOffset; 1484 return fp() + StandardFrameConstants::kCallerSPOffset;
1453 } 1485 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1678 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1647 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1679 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1648 list.Add(frame, zone); 1680 list.Add(frame, zone);
1649 } 1681 }
1650 return list.ToVector(); 1682 return list.ToVector();
1651 } 1683 }
1652 1684
1653 1685
1654 } // namespace internal 1686 } // namespace internal
1655 } // namespace v8 1687 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698