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

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: Rebase to have the test suite expect boxed return values 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
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 const int kStackHandlerSlotCount =
Michael Starzinger 2013/05/07 09:55:44 Move the "kStackHandlerSlotCount" constant into th
853 (StackHandlerConstants::kSize >> kPointerSizeLog2);
854 int i = operands_count - 1;
855 *stack_handler_index = -1;
856 for (; !it.done(); it.Advance()) {
857 StackHandler* handler = it.handler();
858 // Save operands pushed after the handler was pushed.
859 for (; GetOperandSlot(i) < handler->address(); i--) {
860 store->set(i, GetOperand(i));
861 }
862 ASSERT_GE(i + 1, kStackHandlerSlotCount);
863 ASSERT_EQ(handler->address(), GetOperandSlot(i));
864 int next_stack_handler_index = i + 1 - kStackHandlerSlotCount;
865 handler->Unwind(isolate(), store, next_stack_handler_index,
866 Smi::FromInt(*stack_handler_index));
867 *stack_handler_index = next_stack_handler_index;
868 i -= kStackHandlerSlotCount;
869 }
870
871 // Save any remaining operands.
872 for (; i >= 0; i--) {
873 store->set(i, GetOperand(i));
874 }
875 }
876
877
878 void JavaScriptFrame::RestoreOperandStack(FixedArray* store,
879 int stack_handler_index) {
880 int operands_count = store->length();
881 ASSERT_LE(operands_count, ComputeOperandsCount());
882 int i = 0;
883 const int kStackHandlerSlotCount =
Michael Starzinger 2013/05/07 09:55:44 Likewise.
884 (StackHandlerConstants::kSize >> kPointerSizeLog2);
885 while (i <= stack_handler_index) {
886 if (i < stack_handler_index) {
887 // An operand.
888 ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
889 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
890 i++;
891 } else {
892 // A stack handler.
893 ASSERT_EQ(i, stack_handler_index);
894 // The FixedArray store grows up. The stack grows down. So the operand
895 // slot for i actually points to the bottom of the top word in the
896 // handler. The base of the StackHandler* is the address of the bottom
897 // word, which will be the last slot that is in the handler.
898 int handler_slot_index = i + kStackHandlerSlotCount - 1;
899 StackHandler *handler =
900 StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
901 Object *data = handler->Rewind(isolate(), store, i, fp());
902 stack_handler_index = Smi::cast(data)->value();
903 i += kStackHandlerSlotCount;
904 }
905 }
906
907 for (; i < operands_count; i++) {
908 ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
909 Memory::Object_at(GetOperandSlot(i)) = store->get(i);
910 }
911 }
912
913
843 void FrameSummary::Print() { 914 void FrameSummary::Print() {
844 PrintF("receiver: "); 915 PrintF("receiver: ");
845 receiver_->ShortPrint(); 916 receiver_->ShortPrint();
846 PrintF("\nfunction: "); 917 PrintF("\nfunction: ");
847 function_->shared()->DebugName()->ShortPrint(); 918 function_->shared()->DebugName()->ShortPrint();
848 PrintF("\ncode: "); 919 PrintF("\ncode: ");
849 code_->ShortPrint(); 920 code_->ShortPrint();
850 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); 921 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT");
851 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); 922 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT");
852 PrintF("\npc: %d\n", offset_); 923 PrintF("\npc: %d\n", offset_);
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer); 1502 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
1432 entry->safepoint_entry.Reset(); 1503 entry->safepoint_entry.Reset();
1433 entry->inner_pointer = inner_pointer; 1504 entry->inner_pointer = inner_pointer;
1434 } 1505 }
1435 return entry; 1506 return entry;
1436 } 1507 }
1437 1508
1438 1509
1439 // ------------------------------------------------------------------------- 1510 // -------------------------------------------------------------------------
1440 1511
1512
1513 void StackHandler::Unwind(Isolate* isolate, FixedArray* array, int offset,
Michael Starzinger 2013/05/07 09:55:44 style: Better put each argument on a single line,
1514 Object* data) const {
1515 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
1516 ASSERT_LE(0, offset);
1517 ASSERT_GE(array->length(), offset + 5);
1518 array->set(offset, data); // next
1519 array->set(offset + 1, *code_address()); // code
1520 uintptr_t state =
1521 Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset);
1522 // Convert state to 31-bit signed integer, so it fits in a Smi.
1523 ASSERT(state < (1U << (32 - kSmiTagSize)));
1524 int int_state = static_cast<int>(state << kSmiTagSize) >> kSmiTagSize;
1525 Smi *smi_state = Smi::FromInt(int_state);
1526 array->set(offset + 2, smi_state); // state
1527 array->set(offset + 3, *context_address()); // context
1528 array->set(offset + 4, Smi::FromInt(0)); // fp
1529
1530 *isolate->handler_address() = next()->address();
1531 }
1532
1533
1534 Object* StackHandler::Rewind(Isolate* isolate, FixedArray* array, int offset,
Michael Starzinger 2013/05/07 09:55:44 style: Likewise.
1535 Address fp) {
1536 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
1537 ASSERT_LE(0, offset);
1538 ASSERT_GE(array->length(), offset + 5);
1539 Object *data = array->get(offset);
1540 Code *code = Code::cast(array->get(offset + 1));
1541 Smi *smi_state = Smi::cast(array->get(offset + 2));
1542 int int_state = smi_state->value();
1543 // Convert saved state from Smi to 31-bit unsigned integer.
1544 unsigned state =
1545 static_cast<unsigned>(int_state << kSmiTagSize) >> kSmiTagSize;
Michael Starzinger 2013/05/07 09:55:44 I think this conversion is broken on 64-bit system
1546 Object *context = array->get(offset + 3);
1547 ASSERT_EQ(Smi::FromInt(0), array->get(offset + 4));
1548
1549 Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
1550 *isolate->handler_address();
Michael Starzinger 2013/05/07 09:55:44 nit: Indentation is off.
1551 Memory::Object_at(address() + StackHandlerConstants::kCodeOffset) = code;
1552 Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset) = state;
1553 Memory::Object_at(address() + StackHandlerConstants::kContextOffset) =
1554 context;
1555 Memory::Address_at(address() + StackHandlerConstants::kFPOffset) = fp;
1556
1557 *isolate->handler_address() = address();
1558
1559 return data;
1560 }
1561
1562
1563 // -------------------------------------------------------------------------
1564
1441 int NumRegs(RegList reglist) { 1565 int NumRegs(RegList reglist) {
1442 return CompilerIntrinsics::CountSetBits(reglist); 1566 return CompilerIntrinsics::CountSetBits(reglist);
1443 } 1567 }
1444 1568
1445 1569
1446 struct JSCallerSavedCodeData { 1570 struct JSCallerSavedCodeData {
1447 int reg_code[kNumJSCallerSaved]; 1571 int reg_code[kNumJSCallerSaved];
1448 }; 1572 };
1449 1573
1450 JSCallerSavedCodeData caller_saved_code_data; 1574 JSCallerSavedCodeData caller_saved_code_data;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 ZoneList<StackFrame*> list(10, zone); 1618 ZoneList<StackFrame*> list(10, zone);
1495 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { 1619 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) {
1496 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); 1620 StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
1497 list.Add(frame, zone); 1621 list.Add(frame, zone);
1498 } 1622 }
1499 return list.ToVector(); 1623 return list.ToVector();
1500 } 1624 }
1501 1625
1502 1626
1503 } } // namespace v8::internal 1627 } } // namespace v8::internal
OLDNEW
« src/frames.h ('K') | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698