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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 240053010: Return Object* instead of MaybeObject* from runtime calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cmpp Created 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap-inl.h ('k') | src/ia32/regexp-macro-assembler-ia32.cc » ('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 2566 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 } 2577 }
2578 } 2578 }
2579 2579
2580 2580
2581 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 2581 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
2582 CEntryStub stub(1, kDontSaveFPRegs); 2582 CEntryStub stub(1, kDontSaveFPRegs);
2583 stub.GetCode(isolate); 2583 stub.GetCode(isolate);
2584 } 2584 }
2585 2585
2586 2586
2587 void CEntryStub::GenerateCore(MacroAssembler* masm, 2587 void CEntryStub::Generate(MacroAssembler* masm) {
2588 Label* throw_normal_exception, 2588 // eax: number of arguments including receiver
2589 Label* throw_termination_exception,
2590 bool do_gc,
2591 bool always_allocate_scope) {
2592 // eax: result parameter for PerformGC, if any
2593 // ebx: pointer to C function (C callee-saved) 2589 // ebx: pointer to C function (C callee-saved)
2594 // ebp: frame pointer (restored after C call) 2590 // ebp: frame pointer (restored after C call)
2595 // esp: stack pointer (restored after C call) 2591 // esp: stack pointer (restored after C call)
2592 // esi: current context (C callee-saved)
2593 // edi: JS function of the caller (C callee-saved)
2594
2595 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2596
2597 // Enter the exit frame that transitions from JavaScript to C++.
2598 __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
2599
2600 // ebx: pointer to C function (C callee-saved)
2601 // ebp: frame pointer (restored after C call)
2602 // esp: stack pointer (restored after C call)
2596 // edi: number of arguments including receiver (C callee-saved) 2603 // edi: number of arguments including receiver (C callee-saved)
2597 // esi: pointer to the first argument (C callee-saved) 2604 // esi: pointer to the first argument (C callee-saved)
2598 2605
2599 // Result returned in eax, or eax+edx if result_size_ is 2. 2606 // Result returned in eax, or eax+edx if result_size_ is 2.
2600 2607
2608 Isolate* isolate = masm->isolate();
2609
2601 // Check stack alignment. 2610 // Check stack alignment.
2602 if (FLAG_debug_code) { 2611 if (FLAG_debug_code) {
2603 __ CheckStackAlignment(); 2612 __ CheckStackAlignment();
2604 } 2613 }
2605 2614
2606 if (do_gc) {
2607 // Pass failure code returned from last attempt as first argument to
2608 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
2609 // stack alignment is known to be correct. This function takes one argument
2610 // which is passed on the stack, and we know that the stack has been
2611 // prepared to pass at least one argument.
2612 __ mov(Operand(esp, 1 * kPointerSize),
2613 Immediate(ExternalReference::isolate_address(masm->isolate())));
2614 __ mov(Operand(esp, 0 * kPointerSize), eax); // Result.
2615 __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY);
2616 }
2617
2618 ExternalReference scope_depth =
2619 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
2620 if (always_allocate_scope) {
2621 __ inc(Operand::StaticVariable(scope_depth));
2622 }
2623
2624 // Call C function. 2615 // Call C function.
2625 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. 2616 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
2626 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. 2617 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
2627 __ mov(Operand(esp, 2 * kPointerSize), 2618 __ mov(Operand(esp, 2 * kPointerSize),
2628 Immediate(ExternalReference::isolate_address(masm->isolate()))); 2619 Immediate(ExternalReference::isolate_address(isolate)));
2629 __ call(ebx); 2620 __ call(ebx);
2630 // Result is in eax or edx:eax - do not destroy these registers! 2621 // Result is in eax or edx:eax - do not destroy these registers!
2631 2622
2632 if (always_allocate_scope) {
2633 __ dec(Operand::StaticVariable(scope_depth));
2634 }
2635
2636 // Runtime functions should not return 'the hole'. Allowing it to escape may 2623 // Runtime functions should not return 'the hole'. Allowing it to escape may
2637 // lead to crashes in the IC code later. 2624 // lead to crashes in the IC code later.
2638 if (FLAG_debug_code) { 2625 if (FLAG_debug_code) {
2639 Label okay; 2626 Label okay;
2640 __ cmp(eax, masm->isolate()->factory()->the_hole_value()); 2627 __ cmp(eax, isolate->factory()->the_hole_value());
2641 __ j(not_equal, &okay, Label::kNear); 2628 __ j(not_equal, &okay, Label::kNear);
2642 __ int3(); 2629 __ int3();
2643 __ bind(&okay); 2630 __ bind(&okay);
2644 } 2631 }
2645 2632
2646 // Check for failure result. 2633 // Check result for exception sentinel.
2647 Label failure_returned; 2634 Label exception_returned;
2648 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); 2635 __ cmp(eax, isolate->factory()->exception());
2649 __ lea(ecx, Operand(eax, 1)); 2636 __ j(equal, &exception_returned);
2650 // Lower 2 bits of ecx are 0 iff eax has failure tag.
2651 __ test(ecx, Immediate(kFailureTagMask));
2652 __ j(zero, &failure_returned);
2653 2637
2654 ExternalReference pending_exception_address( 2638 ExternalReference pending_exception_address(
2655 Isolate::kPendingExceptionAddress, masm->isolate()); 2639 Isolate::kPendingExceptionAddress, isolate);
2656 2640
2657 // Check that there is no pending exception, otherwise we 2641 // Check that there is no pending exception, otherwise we
2658 // should have returned some failure value. 2642 // should have returned the exception sentinel.
2659 if (FLAG_debug_code) { 2643 if (FLAG_debug_code) {
2660 __ push(edx); 2644 __ push(edx);
2661 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2645 __ mov(edx, Immediate(isolate->factory()->the_hole_value()));
2662 Label okay; 2646 Label okay;
2663 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); 2647 __ cmp(edx, Operand::StaticVariable(pending_exception_address));
2664 // Cannot use check here as it attempts to generate call into runtime. 2648 // Cannot use check here as it attempts to generate call into runtime.
2665 __ j(equal, &okay, Label::kNear); 2649 __ j(equal, &okay, Label::kNear);
2666 __ int3(); 2650 __ int3();
2667 __ bind(&okay); 2651 __ bind(&okay);
2668 __ pop(edx); 2652 __ pop(edx);
2669 } 2653 }
2670 2654
2671 // Exit the JavaScript to C++ exit frame. 2655 // Exit the JavaScript to C++ exit frame.
2672 __ LeaveExitFrame(save_doubles_ == kSaveFPRegs); 2656 __ LeaveExitFrame(save_doubles_ == kSaveFPRegs);
2673 __ ret(0); 2657 __ ret(0);
2674 2658
2675 // Handling of failure. 2659 // Handling of exception.
2676 __ bind(&failure_returned); 2660 __ bind(&exception_returned);
2677
2678 Label retry;
2679 // If the returned exception is RETRY_AFTER_GC continue at retry label
2680 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
2681 __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
2682 __ j(zero, &retry, Label::kNear);
2683 2661
2684 // Retrieve the pending exception. 2662 // Retrieve the pending exception.
2685 __ mov(eax, Operand::StaticVariable(pending_exception_address)); 2663 __ mov(eax, Operand::StaticVariable(pending_exception_address));
2686 2664
2687 // Clear the pending exception. 2665 // Clear the pending exception.
2688 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2666 __ mov(edx, Immediate(isolate->factory()->the_hole_value()));
2689 __ mov(Operand::StaticVariable(pending_exception_address), edx); 2667 __ mov(Operand::StaticVariable(pending_exception_address), edx);
2690 2668
2691 // Special handling of termination exceptions which are uncatchable 2669 // Special handling of termination exceptions which are uncatchable
2692 // by javascript code. 2670 // by javascript code.
2693 __ cmp(eax, masm->isolate()->factory()->termination_exception()); 2671 Label throw_termination_exception;
2694 __ j(equal, throw_termination_exception); 2672 __ cmp(eax, isolate->factory()->termination_exception());
2673 __ j(equal, &throw_termination_exception);
2695 2674
2696 // Handle normal exception. 2675 // Handle normal exception.
2697 __ jmp(throw_normal_exception); 2676 __ Throw(eax);
2698 2677
2699 // Retry. 2678 __ bind(&throw_termination_exception);
2700 __ bind(&retry); 2679 __ ThrowUncatchable(eax);
2701 } 2680 }
2702 2681
2703 2682
2704 void CEntryStub::Generate(MacroAssembler* masm) {
2705 // eax: number of arguments including receiver
2706 // ebx: pointer to C function (C callee-saved)
2707 // ebp: frame pointer (restored after C call)
2708 // esp: stack pointer (restored after C call)
2709 // esi: current context (C callee-saved)
2710 // edi: JS function of the caller (C callee-saved)
2711
2712 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2713
2714 // NOTE: Invocations of builtins may return failure objects instead
2715 // of a proper result. The builtin entry handles this by performing
2716 // a garbage collection and retrying the builtin (twice).
2717
2718 // Enter the exit frame that transitions from JavaScript to C++.
2719 __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
2720
2721 // eax: result parameter for PerformGC, if any (setup below)
2722 // ebx: pointer to builtin function (C callee-saved)
2723 // ebp: frame pointer (restored after C call)
2724 // esp: stack pointer (restored after C call)
2725 // edi: number of arguments including receiver (C callee-saved)
2726 // esi: argv pointer (C callee-saved)
2727
2728 Label throw_normal_exception;
2729 Label throw_termination_exception;
2730
2731 // Call into the runtime system.
2732 GenerateCore(masm,
2733 &throw_normal_exception,
2734 &throw_termination_exception,
2735 false,
2736 false);
2737
2738 // Do space-specific GC and retry runtime call.
2739 GenerateCore(masm,
2740 &throw_normal_exception,
2741 &throw_termination_exception,
2742 true,
2743 false);
2744
2745 // Do full GC and retry runtime call one final time.
2746 Failure* failure = Failure::InternalError();
2747 __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure)));
2748 GenerateCore(masm,
2749 &throw_normal_exception,
2750 &throw_termination_exception,
2751 true,
2752 true);
2753
2754 { FrameScope scope(masm, StackFrame::MANUAL);
2755 __ PrepareCallCFunction(0, eax);
2756 __ CallCFunction(
2757 ExternalReference::out_of_memory_function(masm->isolate()), 0);
2758 }
2759
2760 __ bind(&throw_termination_exception);
2761 __ ThrowUncatchable(eax);
2762
2763 __ bind(&throw_normal_exception);
2764 __ Throw(eax);
2765 }
2766
2767
2768 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { 2683 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
2769 Label invoke, handler_entry, exit; 2684 Label invoke, handler_entry, exit;
2770 Label not_outermost_js, not_outermost_js_2; 2685 Label not_outermost_js, not_outermost_js_2;
2771 2686
2772 ProfileEntryHookStub::MaybeCallEntryHook(masm); 2687 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2773 2688
2774 // Set up frame. 2689 // Set up frame.
2775 __ push(ebp); 2690 __ push(ebp);
2776 __ mov(ebp, esp); 2691 __ mov(ebp, esp);
2777 2692
(...skipping 24 matching lines...) Expand all
2802 // Jump to a faked try block that does the invoke, with a faked catch 2717 // Jump to a faked try block that does the invoke, with a faked catch
2803 // block that sets the pending exception. 2718 // block that sets the pending exception.
2804 __ jmp(&invoke); 2719 __ jmp(&invoke);
2805 __ bind(&handler_entry); 2720 __ bind(&handler_entry);
2806 handler_offset_ = handler_entry.pos(); 2721 handler_offset_ = handler_entry.pos();
2807 // Caught exception: Store result (exception) in the pending exception 2722 // Caught exception: Store result (exception) in the pending exception
2808 // field in the JSEnv and return a failure sentinel. 2723 // field in the JSEnv and return a failure sentinel.
2809 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, 2724 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
2810 masm->isolate()); 2725 masm->isolate());
2811 __ mov(Operand::StaticVariable(pending_exception), eax); 2726 __ mov(Operand::StaticVariable(pending_exception), eax);
2812 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); 2727 __ mov(eax, Immediate(masm->isolate()->factory()->exception()));
2813 __ jmp(&exit); 2728 __ jmp(&exit);
2814 2729
2815 // Invoke: Link this frame into the handler chain. There's only one 2730 // Invoke: Link this frame into the handler chain. There's only one
2816 // handler block in this code object, so its index is 0. 2731 // handler block in this code object, so its index is 0.
2817 __ bind(&invoke); 2732 __ bind(&invoke);
2818 __ PushTryHandler(StackHandler::JS_ENTRY, 0); 2733 __ PushTryHandler(StackHandler::JS_ENTRY, 0);
2819 2734
2820 // Clear any pending exceptions. 2735 // Clear any pending exceptions.
2821 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2736 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
2822 __ mov(Operand::StaticVariable(pending_exception), edx); 2737 __ mov(Operand::StaticVariable(pending_exception), edx);
(...skipping 2347 matching lines...) Expand 10 before | Expand all | Expand 10 after
5170 Operand(ebp, 7 * kPointerSize), 5085 Operand(ebp, 7 * kPointerSize),
5171 NULL); 5086 NULL);
5172 } 5087 }
5173 5088
5174 5089
5175 #undef __ 5090 #undef __
5176 5091
5177 } } // namespace v8::internal 5092 } } // namespace v8::internal
5178 5093
5179 #endif // V8_TARGET_ARCH_IA32 5094 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap-inl.h ('k') | src/ia32/regexp-macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698