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

Unified 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, 8 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 side-by-side diff with in-line comments
Download patch
« src/frames.h ('K') | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/frames.cc
diff --git a/src/frames.cc b/src/frames.cc
index aaf8c79e23256a12d4d3a7fe7bce939f9f604ff8..aff389532da15768571b8d3cfa9a1fea74fe1092 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -840,6 +840,77 @@ void JavaScriptFrame::PrintTop(Isolate* isolate,
}
+void JavaScriptFrame::SaveOperandStack(FixedArray* store,
+ int* stack_handler_index) const {
+ int operands_count = store->length();
+ ASSERT_LE(operands_count, ComputeOperandsCount());
+
+ // Visit the stack in LIFO order, saving operands and stack handlers into the
+ // array. The saved stack handlers store a link to the next stack handler,
+ // which will allow RestoreOperandStack to rewind the handlers.
+ StackHandlerIterator it(this, top_handler());
+ const int kStackHandlerSlotCount =
Michael Starzinger 2013/05/07 09:55:44 Move the "kStackHandlerSlotCount" constant into th
+ (StackHandlerConstants::kSize >> kPointerSizeLog2);
+ int i = operands_count - 1;
+ *stack_handler_index = -1;
+ for (; !it.done(); it.Advance()) {
+ StackHandler* handler = it.handler();
+ // Save operands pushed after the handler was pushed.
+ for (; GetOperandSlot(i) < handler->address(); i--) {
+ store->set(i, GetOperand(i));
+ }
+ ASSERT_GE(i + 1, kStackHandlerSlotCount);
+ ASSERT_EQ(handler->address(), GetOperandSlot(i));
+ int next_stack_handler_index = i + 1 - kStackHandlerSlotCount;
+ handler->Unwind(isolate(), store, next_stack_handler_index,
+ Smi::FromInt(*stack_handler_index));
+ *stack_handler_index = next_stack_handler_index;
+ i -= kStackHandlerSlotCount;
+ }
+
+ // Save any remaining operands.
+ for (; i >= 0; i--) {
+ store->set(i, GetOperand(i));
+ }
+}
+
+
+void JavaScriptFrame::RestoreOperandStack(FixedArray* store,
+ int stack_handler_index) {
+ int operands_count = store->length();
+ ASSERT_LE(operands_count, ComputeOperandsCount());
+ int i = 0;
+ const int kStackHandlerSlotCount =
Michael Starzinger 2013/05/07 09:55:44 Likewise.
+ (StackHandlerConstants::kSize >> kPointerSizeLog2);
+ while (i <= stack_handler_index) {
+ if (i < stack_handler_index) {
+ // An operand.
+ ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
+ Memory::Object_at(GetOperandSlot(i)) = store->get(i);
+ i++;
+ } else {
+ // A stack handler.
+ ASSERT_EQ(i, stack_handler_index);
+ // The FixedArray store grows up. The stack grows down. So the operand
+ // slot for i actually points to the bottom of the top word in the
+ // handler. The base of the StackHandler* is the address of the bottom
+ // word, which will be the last slot that is in the handler.
+ int handler_slot_index = i + kStackHandlerSlotCount - 1;
+ StackHandler *handler =
+ StackHandler::FromAddress(GetOperandSlot(handler_slot_index));
+ Object *data = handler->Rewind(isolate(), store, i, fp());
+ stack_handler_index = Smi::cast(data)->value();
+ i += kStackHandlerSlotCount;
+ }
+ }
+
+ for (; i < operands_count; i++) {
+ ASSERT_EQ(GetOperand(i), isolate()->heap()->the_hole_value());
+ Memory::Object_at(GetOperandSlot(i)) = store->get(i);
+ }
+}
+
+
void FrameSummary::Print() {
PrintF("receiver: ");
receiver_->ShortPrint();
@@ -1438,6 +1509,59 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
// -------------------------------------------------------------------------
+
+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,
+ Object* data) const {
+ STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
+ ASSERT_LE(0, offset);
+ ASSERT_GE(array->length(), offset + 5);
+ array->set(offset, data); // next
+ array->set(offset + 1, *code_address()); // code
+ uintptr_t state =
+ Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset);
+ // Convert state to 31-bit signed integer, so it fits in a Smi.
+ ASSERT(state < (1U << (32 - kSmiTagSize)));
+ int int_state = static_cast<int>(state << kSmiTagSize) >> kSmiTagSize;
+ Smi *smi_state = Smi::FromInt(int_state);
+ array->set(offset + 2, smi_state); // state
+ array->set(offset + 3, *context_address()); // context
+ array->set(offset + 4, Smi::FromInt(0)); // fp
+
+ *isolate->handler_address() = next()->address();
+}
+
+
+Object* StackHandler::Rewind(Isolate* isolate, FixedArray* array, int offset,
Michael Starzinger 2013/05/07 09:55:44 style: Likewise.
+ Address fp) {
+ STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
+ ASSERT_LE(0, offset);
+ ASSERT_GE(array->length(), offset + 5);
+ Object *data = array->get(offset);
+ Code *code = Code::cast(array->get(offset + 1));
+ Smi *smi_state = Smi::cast(array->get(offset + 2));
+ int int_state = smi_state->value();
+ // Convert saved state from Smi to 31-bit unsigned integer.
+ unsigned state =
+ 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
+ Object *context = array->get(offset + 3);
+ ASSERT_EQ(Smi::FromInt(0), array->get(offset + 4));
+
+ Memory::Address_at(address() + StackHandlerConstants::kNextOffset) =
+ *isolate->handler_address();
Michael Starzinger 2013/05/07 09:55:44 nit: Indentation is off.
+ Memory::Object_at(address() + StackHandlerConstants::kCodeOffset) = code;
+ Memory::uintptr_at(address() + StackHandlerConstants::kStateOffset) = state;
+ Memory::Object_at(address() + StackHandlerConstants::kContextOffset) =
+ context;
+ Memory::Address_at(address() + StackHandlerConstants::kFPOffset) = fp;
+
+ *isolate->handler_address() = address();
+
+ return data;
+}
+
+
+// -------------------------------------------------------------------------
+
int NumRegs(RegList reglist) {
return CompilerIntrinsics::CountSetBits(reglist);
}
« 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