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

Side by Side Diff: src/frames.cc

Issue 14031028: Generators save and restore stack handlers (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Rebased before commit Created 7 years, 7 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 } 833 }
834 PrintF(file, ")"); 834 PrintF(file, ")");
835 } 835 }
836 break; 836 break;
837 } 837 }
838 it.Advance(); 838 it.Advance();
839 } 839 }
840 } 840 }
841 841
842 842
843 void JavaScriptFrame::SaveOperandStack(FixedArray* store,
844 int* stack_handler_index) const {
845 int operands_count = store->length();
846 ASSERT_LE(operands_count, ComputeOperandsCount());
847
848 // Visit the stack in LIFO order, saving operands and stack handlers into the
849 // array. The saved stack handlers store a link to the next stack handler,
850 // which will allow RestoreOperandStack to rewind the handlers.
851 StackHandlerIterator it(this, top_handler());
852 int i = operands_count - 1;
853 *stack_handler_index = -1;
854 for (; !it.done(); it.Advance()) {
855 StackHandler* handler = it.handler();
856 // Save operands pushed after the handler was pushed.
857 for (; GetOperandSlot(i) < handler->address(); i--) {
858 store->set(i, GetOperand(i));
859 }
860 ASSERT_GE(i + 1, StackHandlerConstants::kSlotCount);
861 ASSERT_EQ(handler->address(), GetOperandSlot(i));
862 int next_stack_handler_index = i + 1 - StackHandlerConstants::kSlotCount;
863 handler->Unwind(isolate(), store, next_stack_handler_index,
864 *stack_handler_index);
865 *stack_handler_index = next_stack_handler_index;
866 i -= StackHandlerConstants::kSlotCount;
867 }
868
869 // Save any remaining operands.
870 for (; i >= 0; i--) {
871 store->set(i, GetOperand(i));
872 }
873 }
874
875
876 void JavaScriptFrame::RestoreOperandStack(FixedArray* store,
877 int stack_handler_index) {
878 int operands_count = store->length();
879 ASSERT_LE(operands_count, ComputeOperandsCount());
880 int i = 0;
881 while (i <= stack_handler_index) {
882 if (i < stack_handler_index) {
883 // An operand.
884 ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
885 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
886 i++;
887 } else {
888 // A stack handler.
889 ASSERT_EQ(i, stack_handler_index);
890 // The FixedArray store grows up. The stack grows down. So the operand
891 // slot for i actually points to the bottom of the top word in the
892 // handler. The base of the StackHandler* is the address of the bottom
893 // word, which will be the last slot that is in the handler.
894 int handler_slot_index = i + StackHandlerConstants::kSlotCount - 1;
895 StackHandler *handler =
896 StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
897 stack_handler_index = handler->Rewind(isolate(), store, i, fp());
898 i += StackHandlerConstants::kSlotCount;
899 }
900 }
901
902 for (; i < operands_count; i++) {
903 ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
904 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
905 }
906 }
907
908
843 void FrameSummary::Print() { 909 void FrameSummary::Print() {
844 PrintF("receiver: "); 910 PrintF("receiver: ");
845 receiver_->ShortPrint(); 911 receiver_->ShortPrint();
846 PrintF("\nfunction: "); 912 PrintF("\nfunction: ");
847 function_->shared()->DebugName()->ShortPrint(); 913 function_->shared()->DebugName()->ShortPrint();
848 PrintF("\ncode: "); 914 PrintF("\ncode: ");
849 code_->ShortPrint(); 915 code_->ShortPrint();
850 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); 916 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT");
851 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); 917 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT");
852 PrintF("\npc: %d\n", offset_); 918 PrintF("\npc: %d\n", offset_);
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer); 1497 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
1432 entry->safepoint_entry.Reset(); 1498 entry->safepoint_entry.Reset();
1433 entry->inner_pointer = inner_pointer; 1499 entry->inner_pointer = inner_pointer;
1434 } 1500 }
1435 return entry; 1501 return entry;
1436 } 1502 }
1437 1503
1438 1504
1439 // ------------------------------------------------------------------------- 1505 // -------------------------------------------------------------------------
1440 1506
1507
1508 void StackHandler::Unwind(Isolate* isolate,
1509 FixedArray* array,
1510 int offset,
1511 int previous_handler_offset) const {
1512 STATIC_ASSERT(StackHandlerConstants::kSlotCount == 5);
1513 ASSERT_LE(0, offset);
1514 ASSERT_GE(array->length(), offset + 5);
1515 // Unwinding a stack handler into an array chains it in the opposite
1516 // direction, re-using the "next" slot as a "previous" link, so that stack
1517 // handlers can be later re-wound in the correct order. Decode the "state"
1518 // slot into "index" and "kind" and store them separately, using the fp slot.
1519 array->set(offset, Smi::FromInt(previous_handler_offset)); // next
1520 array->set(offset + 1, *code_address()); // code
1521 array->set(offset + 2, Smi::FromInt(static_cast<int>(index()))); // state
1522 array->set(offset + 3, *context_address()); // context
1523 array->set(offset + 4, Smi::FromInt(static_cast<int>(kind()))); // fp
1524
1525 *isolate->handler_address() = next()->address();
1526 }
1527
1528
1529 int StackHandler::Rewind(Isolate* isolate,
1530 FixedArray* array,
1531 int offset,
1532 Address fp) {
1533 STATIC_ASSERT(StackHandlerConstants::kSlotCount == 5);
1534 ASSERT_LE(0, offset);
1535 ASSERT_GE(array->length(), offset + 5);
1536 Smi* prev_handler_offset = Smi::cast(array->get(offset));
1537 Code* code = Code::cast(array->get(offset + 1));
1538 Smi* smi_index = Smi::cast(array->get(offset + 2));
1539 Object* context = array->get(offset + 3);
1540 Smi* smi_kind = Smi::cast(array->get(offset + 4));
1541
1542 unsigned state = KindField::encode(static_cast<Kind>(smi_kind->value())) |
1543 IndexField::encode(static_cast<unsigned>(smi_index->value()));
1544
1545 Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
1546 *isolate->handler_address();
1547 Memory::Object_at(address() + StackHandlerConstants::kCodeOffset) = code;
1548 Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset) = state;
1549 Memory::Object_at(address() + StackHandlerConstants::kContextOffset) =
1550 context;
1551 Memory::Address_at(address() + StackHandlerConstants::kFPOffset) = fp;
1552
1553 *isolate->handler_address() = address();
1554
1555 return prev_handler_offset->value();
1556 }
1557
1558
1559 // -------------------------------------------------------------------------
1560
1441 int NumRegs(RegList reglist) { 1561 int NumRegs(RegList reglist) {
1442 return CompilerIntrinsics::CountSetBits(reglist); 1562 return CompilerIntrinsics::CountSetBits(reglist);
1443 } 1563 }
1444 1564
1445 1565
1446 struct JSCallerSavedCodeData { 1566 struct JSCallerSavedCodeData {
1447 int reg_code[kNumJSCallerSaved]; 1567 int reg_code[kNumJSCallerSaved];
1448 }; 1568 };
1449 1569
1450 JSCallerSavedCodeData caller_saved_code_data; 1570 JSCallerSavedCodeData caller_saved_code_data;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 ZoneList<StackFrame*> list(10, zone); 1614 ZoneList<StackFrame*> list(10, zone);
1495 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1615 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1496 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1616 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1497 list.Add(frame, zone); 1617 list.Add(frame, zone);
1498 } 1618 }
1499 return list.ToVector(); 1619 return list.ToVector();
1500 } 1620 }
1501 1621
1502 1622
1503 } } // namespace v8::internal 1623 } } // 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