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

Side by Side Diff: src/frames.cc

Issue 1010883002: Switch full-codegen from StackHandlers to handler table. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_cleanup-isolate-dead-code
Patch Set: Fix debugger-pause-on-promise-rejection. Created 5 years, 9 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 | « 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/frames.h" 5 #include "src/frames.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 } 373 }
374 374
375 // Fill in the results and return the code. 375 // Fill in the results and return the code.
376 Code* code = entry->code; 376 Code* code = entry->code;
377 *safepoint_entry = entry->safepoint_entry; 377 *safepoint_entry = entry->safepoint_entry;
378 *stack_slots = code->stack_slots(); 378 *stack_slots = code->stack_slots();
379 return code; 379 return code;
380 } 380 }
381 381
382 382
383 bool StackFrame::HasHandler() const {
384 StackHandlerIterator it(this, top_handler());
385 return !it.done();
386 }
387
388
389 #ifdef DEBUG 383 #ifdef DEBUG
390 static bool GcSafeCodeContains(HeapObject* object, Address addr); 384 static bool GcSafeCodeContains(HeapObject* object, Address addr);
391 #endif 385 #endif
392 386
393 387
394 void StackFrame::IteratePc(ObjectVisitor* v, 388 void StackFrame::IteratePc(ObjectVisitor* v,
395 Address* pc_address, 389 Address* pc_address,
396 Code* holder) { 390 Code* holder) {
397 Address pc = *pc_address; 391 Address pc = *pc_address;
398 DCHECK(GcSafeCodeContains(holder, pc)); 392 DCHECK(GcSafeCodeContains(holder, pc));
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp())); 595 reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
602 } 596 }
603 597
604 598
605 void StandardFrame::SetCallerFp(Address caller_fp) { 599 void StandardFrame::SetCallerFp(Address caller_fp) {
606 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) = 600 Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset) =
607 caller_fp; 601 caller_fp;
608 } 602 }
609 603
610 604
611 bool StandardFrame::IsExpressionInsideHandler(int n) const {
612 Address address = GetExpressionAddress(n);
613 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
614 if (it.handler()->includes(address)) return true;
615 }
616 return false;
617 }
618
619
620 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const { 605 void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
621 // Make sure that we're not doing "safe" stack frame iteration. We cannot 606 // Make sure that we're not doing "safe" stack frame iteration. We cannot
622 // possibly find pointers in optimized frames in that state. 607 // possibly find pointers in optimized frames in that state.
623 DCHECK(can_access_heap_objects()); 608 DCHECK(can_access_heap_objects());
624 609
625 // Compute the safepoint information. 610 // Compute the safepoint information.
626 unsigned stack_slots = 0; 611 unsigned stack_slots = 0;
627 SafepointEntry safepoint_entry; 612 SafepointEntry safepoint_entry;
628 Code* code = StackFrame::GetSafepointData( 613 Code* code = StackFrame::GetSafepointData(
629 isolate(), pc(), &safepoint_entry, &stack_slots); 614 isolate(), pc(), &safepoint_entry, &stack_slots);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 return fp() + ExitFrameConstants::kCallerSPDisplacement; 688 return fp() + ExitFrameConstants::kCallerSPDisplacement;
704 } 689 }
705 690
706 691
707 int StubFrame::GetNumberOfIncomingArguments() const { 692 int StubFrame::GetNumberOfIncomingArguments() const {
708 return 0; 693 return 0;
709 } 694 }
710 695
711 696
712 void OptimizedFrame::Iterate(ObjectVisitor* v) const { 697 void OptimizedFrame::Iterate(ObjectVisitor* v) const {
713 #ifdef DEBUG
714 // Make sure that optimized frames do not contain any stack handlers.
715 StackHandlerIterator it(this, top_handler());
716 DCHECK(it.done());
717 #endif
718
719 IterateCompiledFrame(v); 698 IterateCompiledFrame(v);
720 } 699 }
721 700
722 701
723 void JavaScriptFrame::SetParameterValue(int index, Object* value) const { 702 void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
724 Memory::Object_at(GetParameterSlot(index)) = value; 703 Memory::Object_at(GetParameterSlot(index)) = value;
725 } 704 }
726 705
727 706
728 bool JavaScriptFrame::IsConstructor() const { 707 bool JavaScriptFrame::IsConstructor() const {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 int offset = static_cast<int>(pc() - code_pointer->address()); 754 int offset = static_cast<int>(pc() - code_pointer->address());
776 FrameSummary summary(receiver(), 755 FrameSummary summary(receiver(),
777 function(), 756 function(),
778 code_pointer, 757 code_pointer,
779 offset, 758 offset,
780 IsConstructor()); 759 IsConstructor());
781 functions->Add(summary); 760 functions->Add(summary);
782 } 761 }
783 762
784 763
764 int JavaScriptFrame::LookupExceptionHandlerInTable(int* stack_slots) {
765 Code* code = LookupCode();
766 DCHECK(!code->is_optimized_code());
767 HandlerTable* table = HandlerTable::cast(code->handler_table());
768 int pc_offset = static_cast<int>(pc() - code->entry());
769 return table->LookupRange(pc_offset, stack_slots);
770 }
771
772
785 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code, 773 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code,
786 Address pc, FILE* file, 774 Address pc, FILE* file,
787 bool print_line_number) { 775 bool print_line_number) {
788 PrintF(file, "%s", function->IsOptimized() ? "*" : "~"); 776 PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
789 function->PrintName(file); 777 function->PrintName(file);
790 int code_offset = static_cast<int>(pc - code->instruction_start()); 778 int code_offset = static_cast<int>(pc - code->instruction_start());
791 PrintF(file, "+%d", code_offset); 779 PrintF(file, "+%d", code_offset);
792 if (print_line_number) { 780 if (print_line_number) {
793 SharedFunctionInfo* shared = function->shared(); 781 SharedFunctionInfo* shared = function->shared();
794 int source_pos = code->SourcePosition(pc); 782 int source_pos = code->SourcePosition(pc);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 } 824 }
837 PrintF(file, ")"); 825 PrintF(file, ")");
838 } 826 }
839 break; 827 break;
840 } 828 }
841 it.Advance(); 829 it.Advance();
842 } 830 }
843 } 831 }
844 832
845 833
846 void JavaScriptFrame::SaveOperandStack(FixedArray* store, 834 void JavaScriptFrame::SaveOperandStack(FixedArray* store) const {
847 int* stack_handler_index) const {
848 int operands_count = store->length(); 835 int operands_count = store->length();
849 DCHECK_LE(operands_count, ComputeOperandsCount()); 836 DCHECK_LE(operands_count, ComputeOperandsCount());
850 837 for (int i = 0; i < operands_count; i++) {
851 // Visit the stack in LIFO order, saving operands and stack handlers into the
852 // array. The saved stack handlers store a link to the next stack handler,
853 // which will allow RestoreOperandStack to rewind the handlers.
854 StackHandlerIterator it(this, top_handler());
855 int i = operands_count - 1;
856 *stack_handler_index = -1;
857 for (; !it.done(); it.Advance()) {
858 StackHandler* handler = it.handler();
859 // Save operands pushed after the handler was pushed.
860 for (; GetOperandSlot(i) < handler->address(); i--) {
861 store->set(i, GetOperand(i));
862 }
863 DCHECK_GE(i + 1, StackHandlerConstants::kSlotCount);
864 DCHECK_EQ(handler->address(), GetOperandSlot(i));
865 int next_stack_handler_index = i + 1 - StackHandlerConstants::kSlotCount;
866 handler->Unwind(isolate(), store, next_stack_handler_index,
867 *stack_handler_index);
868 *stack_handler_index = next_stack_handler_index;
869 i -= StackHandlerConstants::kSlotCount;
870 }
871
872 // Save any remaining operands.
873 for (; i >= 0; i--) {
874 store->set(i, GetOperand(i)); 838 store->set(i, GetOperand(i));
875 } 839 }
876 } 840 }
877 841
878 842
879 void JavaScriptFrame::RestoreOperandStack(FixedArray* store, 843 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) {
880 int stack_handler_index) {
881 int operands_count = store->length(); 844 int operands_count = store->length();
882 DCHECK_LE(operands_count, ComputeOperandsCount()); 845 DCHECK_LE(operands_count, ComputeOperandsCount());
883 int i = 0; 846 for (int i = 0; i < operands_count; i++) {
884 while (i <= stack_handler_index) {
885 if (i < stack_handler_index) {
886 // An operand.
887 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
888 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
889 i++;
890 } else {
891 // A stack handler.
892 DCHECK_EQ(i, stack_handler_index);
893 // The FixedArray store grows up. The stack grows down. So the operand
894 // slot for i actually points to the bottom of the top word in the
895 // handler. The base of the StackHandler* is the address of the bottom
896 // word, which will be the last slot that is in the handler.
897 int handler_slot_index = i + StackHandlerConstants::kSlotCount - 1;
898 StackHandler *handler =
899 StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
900 stack_handler_index = handler->Rewind(isolate(), store, i, fp());
901 i += StackHandlerConstants::kSlotCount;
902 }
903 }
904
905 for (; i < operands_count; i++) {
906 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); 847 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
907 Memory::Object_at(GetOperandSlot(i)) = store->get(i); 848 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
908 } 849 }
909 } 850 }
910 851
911 852
912 void FrameSummary::Print() { 853 void FrameSummary::Print() {
913 PrintF("receiver: "); 854 PrintF("receiver: ");
914 receiver_->ShortPrint(); 855 receiver_->ShortPrint();
915 PrintF("\nfunction: "); 856 PrintF("\nfunction: ");
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 is_constructor = true; 969 is_constructor = true;
1029 } else { 970 } else {
1030 // Skip over operands to advance to the next opcode. 971 // Skip over operands to advance to the next opcode.
1031 it.Skip(Translation::NumberOfOperandsFor(opcode)); 972 it.Skip(Translation::NumberOfOperandsFor(opcode));
1032 } 973 }
1033 } 974 }
1034 DCHECK(!is_constructor); 975 DCHECK(!is_constructor);
1035 } 976 }
1036 977
1037 978
979 int OptimizedFrame::LookupExceptionHandlerInTable(int* stack_slots) {
980 Code* code = LookupCode();
981 DCHECK(code->is_optimized_code());
982 HandlerTable* table = HandlerTable::cast(code->handler_table());
983 int pc_offset = static_cast<int>(pc() - code->entry());
984 *stack_slots = code->stack_slots();
985 return table->LookupReturn(pc_offset);
986 }
987
988
1038 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData( 989 DeoptimizationInputData* OptimizedFrame::GetDeoptimizationData(
1039 int* deopt_index) { 990 int* deopt_index) {
1040 DCHECK(is_optimized()); 991 DCHECK(is_optimized());
1041 992
1042 JSFunction* opt_function = function(); 993 JSFunction* opt_function = function();
1043 Code* code = opt_function->code(); 994 Code* code = opt_function->code();
1044 995
1045 // The code object may have been replaced by lazy deoptimization. Fall 996 // The code object may have been replaced by lazy deoptimization. Fall
1046 // back to a slow search in this case to find the original optimized 997 // back to a slow search in this case to find the original optimized
1047 // code object. 998 // code object.
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 } 1230 }
1280 accumulator->Add("\n"); 1231 accumulator->Add("\n");
1281 } 1232 }
1282 1233
1283 // Print the expression stack. 1234 // Print the expression stack.
1284 int expressions_start = stack_locals_count; 1235 int expressions_start = stack_locals_count;
1285 if (expressions_start < expressions_count) { 1236 if (expressions_start < expressions_count) {
1286 accumulator->Add(" // expression stack (top to bottom)\n"); 1237 accumulator->Add(" // expression stack (top to bottom)\n");
1287 } 1238 }
1288 for (int i = expressions_count - 1; i >= expressions_start; i--) { 1239 for (int i = expressions_count - 1; i >= expressions_start; i--) {
1289 if (IsExpressionInsideHandler(i)) continue;
1290 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i)); 1240 accumulator->Add(" [%02d] : %o\n", i, GetExpression(i));
1291 } 1241 }
1292 1242
1293 // Print details about the function. 1243 // Print details about the function.
1294 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) { 1244 if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
1295 std::ostringstream os; 1245 std::ostringstream os;
1296 SharedFunctionInfo* shared = function->shared(); 1246 SharedFunctionInfo* shared = function->shared();
1297 os << "--------- s o u r c e c o d e ---------\n" 1247 os << "--------- s o u r c e c o d e ---------\n"
1298 << SourceCodeOf(shared, FLAG_max_stack_trace_source_length) 1248 << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
1299 << "\n-----------------------------------------\n"; 1249 << "\n-----------------------------------------\n";
(...skipping 28 matching lines...) Expand all
1328 accumulator->Add(" // not passed to callee"); 1278 accumulator->Add(" // not passed to callee");
1329 } 1279 }
1330 accumulator->Add("\n"); 1280 accumulator->Add("\n");
1331 } 1281 }
1332 1282
1333 accumulator->Add("}\n\n"); 1283 accumulator->Add("}\n\n");
1334 } 1284 }
1335 1285
1336 1286
1337 void EntryFrame::Iterate(ObjectVisitor* v) const { 1287 void EntryFrame::Iterate(ObjectVisitor* v) const {
1338 StackHandlerIterator it(this, top_handler());
1339 DCHECK(!it.done());
1340 StackHandler* handler = it.handler();
1341 handler->Iterate(v, LookupCode());
1342 #ifdef DEBUG
1343 // Make sure that the entry frame does not contain more than one
1344 // stack handler.
1345 it.Advance();
1346 DCHECK(it.done());
1347 #endif
1348 IteratePc(v, pc_address(), LookupCode()); 1288 IteratePc(v, pc_address(), LookupCode());
1349 } 1289 }
1350 1290
1351 1291
1352 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { 1292 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
1353 const int offset = StandardFrameConstants::kLastObjectOffset; 1293 const int offset = StandardFrameConstants::kLastObjectOffset;
1354 Object** base = &Memory::Object_at(sp()); 1294 Object** base = &Memory::Object_at(sp());
1355 Object** limit = &Memory::Object_at(fp() + offset) + 1; 1295 Object** limit = &Memory::Object_at(fp() + offset) + 1;
1356 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
1357 StackHandler* handler = it.handler();
1358 // Traverse pointers down to - but not including - the next
1359 // handler in the handler chain. Update the base to skip the
1360 // handler and allow the handler to traverse its own pointers.
1361 const Address address = handler->address();
1362 v->VisitPointers(base, reinterpret_cast<Object**>(address));
1363 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
1364 // Traverse the pointers in the handler itself.
1365 handler->Iterate(v, LookupCode());
1366 }
1367 v->VisitPointers(base, limit); 1296 v->VisitPointers(base, limit);
1368 } 1297 }
1369 1298
1370 1299
1371 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { 1300 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
1372 IterateExpressions(v); 1301 IterateExpressions(v);
1373 IteratePc(v, pc_address(), LookupCode()); 1302 IteratePc(v, pc_address(), LookupCode());
1374 } 1303 }
1375 1304
1376 1305
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 entry->safepoint_entry.Reset(); 1451 entry->safepoint_entry.Reset();
1523 entry->inner_pointer = inner_pointer; 1452 entry->inner_pointer = inner_pointer;
1524 } 1453 }
1525 return entry; 1454 return entry;
1526 } 1455 }
1527 1456
1528 1457
1529 // ------------------------------------------------------------------------- 1458 // -------------------------------------------------------------------------
1530 1459
1531 1460
1532 void StackHandler::Unwind(Isolate* isolate,
1533 FixedArray* array,
1534 int offset,
1535 int previous_handler_offset) const {
1536 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 3);
1537 DCHECK_LE(0, offset);
1538 DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
1539 // Unwinding a stack handler into an array chains it in the opposite
1540 // direction, re-using the "next" slot as a "previous" link, so that stack
1541 // handlers can be later re-wound in the correct order.
1542 int s = Memory::int_at(address() + StackHandlerConstants::kStateIntOffset);
1543 array->set(offset, Smi::FromInt(previous_handler_offset)); // next
1544 array->set(offset + 1, Smi::FromInt(static_cast<int>(s))); // state
1545 array->set(offset + 2, *context_address()); // context
1546
1547 *isolate->handler_address() = next()->address();
1548 }
1549
1550
1551 int StackHandler::Rewind(Isolate* isolate,
1552 FixedArray* array,
1553 int offset,
1554 Address fp) {
1555 STATIC_ASSERT(StackHandlerConstants::kSlotCount >= 3);
1556 DCHECK_LE(0, offset);
1557 DCHECK_GE(array->length(), offset + StackHandlerConstants::kSlotCount);
1558 Smi* prev_handler_offset = Smi::cast(array->get(offset));
1559 Smi* smi_state = Smi::cast(array->get(offset + 1));
1560 Object* context = array->get(offset + 2);
1561
1562 Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
1563 *isolate->handler_address();
1564 Memory::int_at(address() + StackHandlerConstants::kStateIntOffset) =
1565 smi_state->value();
1566 Memory::Object_at(address() + StackHandlerConstants::kContextOffset) =
1567 context;
1568
1569 *isolate->handler_address() = address();
1570
1571 return prev_handler_offset->value();
1572 }
1573
1574
1575 // -------------------------------------------------------------------------
1576
1577 int NumRegs(RegList reglist) { return base::bits::CountPopulation32(reglist); } 1461 int NumRegs(RegList reglist) { return base::bits::CountPopulation32(reglist); }
1578 1462
1579 1463
1580 struct JSCallerSavedCodeData { 1464 struct JSCallerSavedCodeData {
1581 int reg_code[kNumJSCallerSaved]; 1465 int reg_code[kNumJSCallerSaved];
1582 }; 1466 };
1583 1467
1584 JSCallerSavedCodeData caller_saved_code_data; 1468 JSCallerSavedCodeData caller_saved_code_data;
1585 1469
1586 void SetUpJSCallerSavedCodeData() { 1470 void SetUpJSCallerSavedCodeData() {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 ZoneList<StackFrame*> list(10, zone); 1514 ZoneList<StackFrame*> list(10, zone);
1631 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1515 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1632 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1516 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1633 list.Add(frame, zone); 1517 list.Add(frame, zone);
1634 } 1518 }
1635 return list.ToVector(); 1519 return list.ToVector();
1636 } 1520 }
1637 1521
1638 1522
1639 } } // namespace v8::internal 1523 } } // 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