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

Side by Side Diff: src/runtime.cc

Issue 14031028: Generators save and restore stack handlers (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Use int instead of Smi* in Unwind / Rewind 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 2415 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 } else { 2426 } else {
2427 MaybeObject* maybe_generator = 2427 MaybeObject* maybe_generator =
2428 isolate->heap()->AllocateJSGeneratorObject(function); 2428 isolate->heap()->AllocateJSGeneratorObject(function);
2429 if (!maybe_generator->To(&generator)) return maybe_generator; 2429 if (!maybe_generator->To(&generator)) return maybe_generator;
2430 } 2430 }
2431 generator->set_function(function); 2431 generator->set_function(function);
2432 generator->set_context(Context::cast(frame->context())); 2432 generator->set_context(Context::cast(frame->context()));
2433 generator->set_receiver(frame->receiver()); 2433 generator->set_receiver(frame->receiver());
2434 generator->set_continuation(0); 2434 generator->set_continuation(0);
2435 generator->set_operand_stack(isolate->heap()->empty_fixed_array()); 2435 generator->set_operand_stack(isolate->heap()->empty_fixed_array());
2436 generator->set_stack_handler_index(-1);
2436 2437
2437 return generator; 2438 return generator;
2438 } 2439 }
2439 2440
2440 2441
2441 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { 2442 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) {
2442 NoHandleAllocation ha(isolate); 2443 NoHandleAllocation ha(isolate);
2443 ASSERT(args.length() == 1); 2444 ASSERT(args.length() == 1);
2444 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); 2445 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
2445 2446
2446 JavaScriptFrameIterator stack_iterator(isolate); 2447 JavaScriptFrameIterator stack_iterator(isolate);
2447 JavaScriptFrame* frame = stack_iterator.frame(); 2448 JavaScriptFrame* frame = stack_iterator.frame();
2448 JSFunction* function = JSFunction::cast(frame->function()); 2449 JSFunction* function = JSFunction::cast(frame->function());
2449 RUNTIME_ASSERT(function->shared()->is_generator()); 2450 RUNTIME_ASSERT(function->shared()->is_generator());
2450 ASSERT_EQ(function, generator_object->function()); 2451 ASSERT_EQ(function, generator_object->function());
2451 2452
2452 // We expect there to be at least two values on the operand stack: the return 2453 // We expect there to be at least two values on the operand stack: the return
2453 // value of the yield expression, and the argument to this runtime call. 2454 // value of the yield expression, and the argument to this runtime call.
2454 // Neither of those should be saved. 2455 // Neither of those should be saved.
2455 int operands_count = frame->ComputeOperandsCount(); 2456 int operands_count = frame->ComputeOperandsCount();
2456 ASSERT(operands_count >= 2); 2457 ASSERT(operands_count >= 2);
2457 operands_count -= 2; 2458 operands_count -= 2;
2458 2459
2459 if (operands_count == 0) { 2460 if (operands_count == 0) {
2460 ASSERT_EQ(generator_object->operand_stack(), 2461 ASSERT_EQ(generator_object->operand_stack(),
2461 isolate->heap()->empty_fixed_array()); 2462 isolate->heap()->empty_fixed_array());
2463 ASSERT_EQ(generator_object->stack_handler_index(), -1);
2462 // If there are no operands on the stack, there shouldn't be a handler 2464 // If there are no operands on the stack, there shouldn't be a handler
2463 // active either. 2465 // active either.
2464 ASSERT(!frame->HasHandler()); 2466 ASSERT(!frame->HasHandler());
2465 } else { 2467 } else {
2466 if (frame->HasHandler()) { 2468 int stack_handler_index = -1;
2467 // TODO(wingo): Unwind the stack handlers. 2469 MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count);
2468 UNIMPLEMENTED();
2469 }
2470
2471 FixedArray* operand_stack; 2470 FixedArray* operand_stack;
2472 MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count);
2473 if (!alloc->To(&operand_stack)) return alloc; 2471 if (!alloc->To(&operand_stack)) return alloc;
2474 2472 frame->SaveOperandStack(operand_stack, &stack_handler_index);
2475 for (int i = 0; i < operands_count; i++) {
2476 operand_stack->set(i, frame->GetOperand(i));
2477 }
2478 generator_object->set_operand_stack(operand_stack); 2473 generator_object->set_operand_stack(operand_stack);
2474 generator_object->set_stack_handler_index(stack_handler_index);
2479 } 2475 }
2480 2476
2481 // Set continuation down here to avoid side effects if the operand stack 2477 // Set continuation down here to avoid side effects if the operand stack
2482 // allocation fails. 2478 // allocation fails.
2483 intptr_t offset = frame->pc() - function->code()->instruction_start(); 2479 intptr_t offset = frame->pc() - function->code()->instruction_start();
2484 ASSERT(offset > 0 && Smi::IsValid(offset)); 2480 ASSERT(offset > 0 && Smi::IsValid(offset));
2485 generator_object->set_continuation(static_cast<int>(offset)); 2481 generator_object->set_continuation(static_cast<int>(offset));
2486 2482
2487 // It's possible for the context to be other than the initial context even if 2483 // It's possible for the context to be other than the initial context even if
2488 // there is no stack handler active. For example, this is the case in the 2484 // there is no stack handler active. For example, this is the case in the
(...skipping 29 matching lines...) Expand all
2518 2514
2519 Address pc = generator_object->function()->code()->instruction_start(); 2515 Address pc = generator_object->function()->code()->instruction_start();
2520 int offset = generator_object->continuation(); 2516 int offset = generator_object->continuation();
2521 ASSERT(offset > 0); 2517 ASSERT(offset > 0);
2522 frame->set_pc(pc + offset); 2518 frame->set_pc(pc + offset);
2523 generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting); 2519 generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
2524 2520
2525 FixedArray* operand_stack = generator_object->operand_stack(); 2521 FixedArray* operand_stack = generator_object->operand_stack();
2526 int operands_count = operand_stack->length(); 2522 int operands_count = operand_stack->length();
2527 if (operands_count != 0) { 2523 if (operands_count != 0) {
2528 // TODO(wingo): Rewind stack handlers. However until 2524 frame->RestoreOperandStack(operand_stack,
2529 // SuspendJSGeneratorObject unwinds them, we won't see frames with stack 2525 generator_object->stack_handler_index());
2530 // handlers here.
2531 for (int i = 0; i < operands_count; i++) {
2532 ASSERT_EQ(frame->GetOperand(i), isolate->heap()->the_hole_value());
2533 Memory::Object_at(frame->GetOperandSlot(i)) = operand_stack->get(i);
2534 }
2535 generator_object->set_operand_stack(isolate->heap()->empty_fixed_array()); 2526 generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
2527 generator_object->set_stack_handler_index(-1);
2536 } 2528 }
2537 2529
2538 JSGeneratorObject::ResumeMode resume_mode = 2530 JSGeneratorObject::ResumeMode resume_mode =
2539 static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int); 2531 static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
2540 switch (resume_mode) { 2532 switch (resume_mode) {
2541 case JSGeneratorObject::SEND: 2533 case JSGeneratorObject::SEND:
2542 return value; 2534 return value;
2543 case JSGeneratorObject::THROW: 2535 case JSGeneratorObject::THROW:
2544 return isolate->Throw(value); 2536 return isolate->Throw(value);
2545 } 2537 }
(...skipping 10823 matching lines...) Expand 10 before | Expand all | Expand 10 after
13369 // Handle last resort GC and make sure to allow future allocations 13361 // Handle last resort GC and make sure to allow future allocations
13370 // to grow the heap without causing GCs (if possible). 13362 // to grow the heap without causing GCs (if possible).
13371 isolate->counters()->gc_last_resort_from_js()->Increment(); 13363 isolate->counters()->gc_last_resort_from_js()->Increment();
13372 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13364 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13373 "Runtime::PerformGC"); 13365 "Runtime::PerformGC");
13374 } 13366 }
13375 } 13367 }
13376 13368
13377 13369
13378 } } // namespace v8::internal 13370 } } // namespace v8::internal
OLDNEW
« src/frames.cc ('K') | « src/objects-inl.h ('k') | src/v8memory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698