OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 | |
Michael Starzinger
2013/05/07 20:21:18
nit: The comment at the end of the line is outdate
Michael Starzinger
2013/05/07 20:25:23
Ah, OK, now I got it, the comments reflect the ori
| |
1522 array->set(offset + 3, *context_address()); // context | |
1523 array->set(offset + 4, Smi::FromInt(static_cast<int>(kind()))); // fp | |
Michael Starzinger
2013/05/07 20:21:18
nit: The comment at the end of the line is outdate
Michael Starzinger
2013/05/07 20:25:23
Please ignore this comment.
| |
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)); | |
Michael Starzinger
2013/05/07 20:21:18
style: We stick the '*' onto the type (i.e. to the
| |
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())); | |
Michael Starzinger
2013/05/07 20:21:18
nit: Indentation is off.
| |
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 Loading... | |
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 |
OLD | NEW |