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

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: fix string allocation 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
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)
2596 // edi: number of arguments including receiver (C callee-saved) 2592 // edi: number of arguments including receiver (C callee-saved)
2597 // esi: pointer to the first argument (C callee-saved) 2593 // esi: pointer to the first argument (C callee-saved)
2594 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2595
2596 // NOTE: Invocations of builtins may return failure objects instead
Jakob Kummerow 2014/04/17 14:20:12 I think this is outdated ;-)
2597 // of a proper result. The builtin entry handles this by performing
2598 // a garbage collection and retrying the builtin (twice).
2599
2600 // Enter the exit frame that transitions from JavaScript to C++.
2601 __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
2598 2602
2599 // Result returned in eax, or eax+edx if result_size_ is 2. 2603 // Result returned in eax, or eax+edx if result_size_ is 2.
2604 // Call into the runtime system.
2600 2605
2601 // Check stack alignment. 2606 // Check stack alignment.
2602 if (FLAG_debug_code) { 2607 if (FLAG_debug_code) {
2603 __ CheckStackAlignment(); 2608 __ CheckStackAlignment();
2604 } 2609 }
2605 2610
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. 2611 // Call C function.
2625 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. 2612 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
2626 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. 2613 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
2627 __ mov(Operand(esp, 2 * kPointerSize), 2614 __ mov(Operand(esp, 2 * kPointerSize),
2628 Immediate(ExternalReference::isolate_address(masm->isolate()))); 2615 Immediate(ExternalReference::isolate_address(masm->isolate())));
2629 __ call(ebx); 2616 __ call(ebx);
2630 // Result is in eax or edx:eax - do not destroy these registers! 2617 // Result is in eax or edx:eax - do not destroy these registers!
2631 2618
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 2619 // Runtime functions should not return 'the hole'. Allowing it to escape may
2637 // lead to crashes in the IC code later. 2620 // lead to crashes in the IC code later.
2638 if (FLAG_debug_code) { 2621 if (FLAG_debug_code) {
2639 Label okay; 2622 Label okay;
2640 __ cmp(eax, masm->isolate()->factory()->the_hole_value()); 2623 __ cmp(eax, masm->isolate()->factory()->the_hole_value());
2641 __ j(not_equal, &okay, Label::kNear); 2624 __ j(not_equal, &okay, Label::kNear);
2642 __ int3(); 2625 __ int3();
2643 __ bind(&okay); 2626 __ bind(&okay);
2644 } 2627 }
2645 2628
2646 // Check for failure result.
2647 Label failure_returned; 2629 Label failure_returned;
2648 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); 2630 __ cmp(eax, masm->isolate()->factory()->exception());
2649 __ lea(ecx, Operand(eax, 1)); 2631 __ j(equal, &failure_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 2632
2654 ExternalReference pending_exception_address( 2633 ExternalReference pending_exception_address(
2655 Isolate::kPendingExceptionAddress, masm->isolate()); 2634 Isolate::kPendingExceptionAddress, masm->isolate());
2656 2635
2657 // Check that there is no pending exception, otherwise we 2636 // Check that there is no pending exception, otherwise we
2658 // should have returned some failure value. 2637 // should have returned the exception sentinel.
2659 if (FLAG_debug_code) { 2638 if (FLAG_debug_code) {
2660 __ push(edx); 2639 __ push(edx);
2661 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2640 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
2662 Label okay; 2641 Label okay;
2663 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); 2642 __ cmp(edx, Operand::StaticVariable(pending_exception_address));
2664 // Cannot use check here as it attempts to generate call into runtime. 2643 // Cannot use check here as it attempts to generate call into runtime.
2665 __ j(equal, &okay, Label::kNear); 2644 __ j(equal, &okay, Label::kNear);
2666 __ int3(); 2645 __ int3();
2667 __ bind(&okay); 2646 __ bind(&okay);
2668 __ pop(edx); 2647 __ pop(edx);
2669 } 2648 }
2670 2649
2671 // Exit the JavaScript to C++ exit frame. 2650 // Exit the JavaScript to C++ exit frame.
2672 __ LeaveExitFrame(save_doubles_ == kSaveFPRegs); 2651 __ LeaveExitFrame(save_doubles_ == kSaveFPRegs);
2673 __ ret(0); 2652 __ ret(0);
2674 2653
2675 // Handling of failure. 2654 // Handling of failure.
2676 __ bind(&failure_returned); 2655 __ bind(&failure_returned);
2677 2656
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
2684 // Retrieve the pending exception. 2657 // Retrieve the pending exception.
2685 __ mov(eax, Operand::StaticVariable(pending_exception_address)); 2658 __ mov(eax, Operand::StaticVariable(pending_exception_address));
2686 2659
2687 // Clear the pending exception. 2660 // Clear the pending exception.
2688 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2661 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
2689 __ mov(Operand::StaticVariable(pending_exception_address), edx); 2662 __ mov(Operand::StaticVariable(pending_exception_address), edx);
2690 2663
2691 // Special handling of termination exceptions which are uncatchable 2664 // Special handling of termination exceptions which are uncatchable
2692 // by javascript code. 2665 // by javascript code.
2666 Label throw_termination_exception;
2693 __ cmp(eax, masm->isolate()->factory()->termination_exception()); 2667 __ cmp(eax, masm->isolate()->factory()->termination_exception());
2694 __ j(equal, throw_termination_exception); 2668 __ j(equal, &throw_termination_exception);
2695 2669
2696 // Handle normal exception. 2670 // Handle normal exception.
2697 __ jmp(throw_normal_exception); 2671 __ Throw(eax);
2698 2672
2699 // Retry. 2673 __ bind(&throw_termination_exception);
2700 __ bind(&retry); 2674 __ ThrowUncatchable(eax);
2701 } 2675 }
2702 2676
2703 2677
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) { 2678 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
2769 Label invoke, handler_entry, exit; 2679 Label invoke, handler_entry, exit;
2770 Label not_outermost_js, not_outermost_js_2; 2680 Label not_outermost_js, not_outermost_js_2;
2771 2681
2772 ProfileEntryHookStub::MaybeCallEntryHook(masm); 2682 ProfileEntryHookStub::MaybeCallEntryHook(masm);
2773 2683
2774 // Set up frame. 2684 // Set up frame.
2775 __ push(ebp); 2685 __ push(ebp);
2776 __ mov(ebp, esp); 2686 __ mov(ebp, esp);
2777 2687
(...skipping 24 matching lines...) Expand all
2802 // Jump to a faked try block that does the invoke, with a faked catch 2712 // Jump to a faked try block that does the invoke, with a faked catch
2803 // block that sets the pending exception. 2713 // block that sets the pending exception.
2804 __ jmp(&invoke); 2714 __ jmp(&invoke);
2805 __ bind(&handler_entry); 2715 __ bind(&handler_entry);
2806 handler_offset_ = handler_entry.pos(); 2716 handler_offset_ = handler_entry.pos();
2807 // Caught exception: Store result (exception) in the pending exception 2717 // Caught exception: Store result (exception) in the pending exception
2808 // field in the JSEnv and return a failure sentinel. 2718 // field in the JSEnv and return a failure sentinel.
2809 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, 2719 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
2810 masm->isolate()); 2720 masm->isolate());
2811 __ mov(Operand::StaticVariable(pending_exception), eax); 2721 __ mov(Operand::StaticVariable(pending_exception), eax);
2812 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); 2722 __ mov(eax, Immediate(masm->isolate()->factory()->exception()));
2813 __ jmp(&exit); 2723 __ jmp(&exit);
2814 2724
2815 // Invoke: Link this frame into the handler chain. There's only one 2725 // Invoke: Link this frame into the handler chain. There's only one
2816 // handler block in this code object, so its index is 0. 2726 // handler block in this code object, so its index is 0.
2817 __ bind(&invoke); 2727 __ bind(&invoke);
2818 __ PushTryHandler(StackHandler::JS_ENTRY, 0); 2728 __ PushTryHandler(StackHandler::JS_ENTRY, 0);
2819 2729
2820 // Clear any pending exceptions. 2730 // Clear any pending exceptions.
2821 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value())); 2731 __ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
2822 __ mov(Operand::StaticVariable(pending_exception), edx); 2732 __ mov(Operand::StaticVariable(pending_exception), edx);
(...skipping 2347 matching lines...) Expand 10 before | Expand all | Expand 10 after
5170 Operand(ebp, 7 * kPointerSize), 5080 Operand(ebp, 7 * kPointerSize),
5171 NULL); 5081 NULL);
5172 } 5082 }
5173 5083
5174 5084
5175 #undef __ 5085 #undef __
5176 5086
5177 } } // namespace v8::internal 5087 } } // namespace v8::internal
5178 5088
5179 #endif // V8_TARGET_ARCH_IA32 5089 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap-inl.h ('k') | src/ia32/regexp-macro-assembler-ia32.cc » ('j') | src/runtime.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698