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

Side by Side Diff: src/builtins/ia32/builtins-ia32.cc

Issue 2841913003: [WIP] Initial CallFunctionCallback builtin.
Patch Set: Fix wrong register for arm64. Created 3 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
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/builtins/mips/builtins-mips.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/api-arguments.h"
7 #include "src/code-factory.h" 8 #include "src/code-factory.h"
8 #include "src/codegen.h" 9 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 11 #include "src/full-codegen/full-codegen.h"
11 #include "src/ia32/frames-ia32.h" 12 #include "src/ia32/frames-ia32.h"
12 13
13 namespace v8 { 14 namespace v8 {
14 namespace internal { 15 namespace internal {
15 16
16 #define __ ACCESS_MASM(masm) 17 #define __ ACCESS_MASM(masm)
(...skipping 2851 matching lines...) Expand 10 before | Expand all | Expand 10 after
2868 // ----------------------------------- 2869 // -----------------------------------
2869 2870
2870 // CheckSpreadAndPushToStack will push edx to save it. 2871 // CheckSpreadAndPushToStack will push edx to save it.
2871 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); 2872 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
2872 CheckSpreadAndPushToStack(masm); 2873 CheckSpreadAndPushToStack(masm);
2873 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2874 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2874 TailCallMode::kDisallow), 2875 TailCallMode::kDisallow),
2875 RelocInfo::CODE_TARGET); 2876 RelocInfo::CODE_TARGET);
2876 } 2877 }
2877 2878
2879 namespace {
2880
2881 // Prepares stack to put arguments (aligns and so on). Reserves
2882 // space for return value if needed (assumes the return value is a handle).
2883 // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
2884 // etc. Saves context (esi). If space was reserved for return value then
2885 // stores the pointer to the reserved slot into esi.
2886 void PrepareCallApiFunction(MacroAssembler* masm, int argc) {
2887 __ EnterApiExitFrame(argc);
2888 if (__ emit_debug_code()) {
2889 __ mov(esi, Immediate(bit_cast<int32_t>(kZapValue)));
2890 }
2891 }
2892
2893 // Generates an Operand for saving parameters after PrepareCallApiFunction.
2894 Operand ApiParameterOperand(int index) {
2895 return MemOperand(esp, index * kPointerSize);
2896 }
2897
2898 } // namespace
2899
2900 // static
2901 void Builtins::Generate_CallFunctionCallback(MacroAssembler* masm) {
2902 // ----------- S t a t e -------------
2903 // -- eax : the number of arguments (not incl. the receiver)
2904 // -- edx : api function address
2905 // -- esp[0] : return address
2906 // -- esp[4] : holder
2907 // -- esp[8] : isolate
2908 // -- esp[12] : return value default
2909 // -- esp[16] : return value
2910 // -- esp[20] : call data
2911 // -- esp[24] : target
2912 // -- esp[28] : context save
2913 // -- esp[32] : new.target
2914 // -- esp[36] : last argument
2915 // -- esp[32 + argc * 4] : first argument
2916 // -- esp[36 + argc * 4] : receiver
2917 // -----------------------------------
2918 typedef FunctionCallbackArguments FCA;
2919
2920 STATIC_ASSERT(FCA::kNewTargetIndex == 7);
2921 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
2922 STATIC_ASSERT(FCA::kCalleeIndex == 5);
2923 STATIC_ASSERT(FCA::kDataIndex == 4);
2924 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
2925 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
2926 STATIC_ASSERT(FCA::kIsolateIndex == 1);
2927 STATIC_ASSERT(FCA::kHolderIndex == 0);
2928 STATIC_ASSERT(FCA::kArgsLength == 8);
2929
2930 // Compute the pointer to the implicit args on the stack.
2931 __ lea(ebx, MemOperand(esp, kPCOnStackSize));
2932
2933 // API function gets reference to the v8::Arguments. If CPU profiler
2934 // is enabled wrapper function will be called and we need to pass
2935 // address of the callback as additional parameter, always allocate
2936 // space for it.
2937 const int kApiArgc = 1 + 1;
2938
2939 // Allocate the v8::FunctionCallbackInfo structure in the arguments' space
2940 // since it's not controlled by the GC.
2941 const int kApiStackSpace = 3;
2942 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace);
2943 // Initialize FunctionCallbackInfo::implicit_args_.
2944 __ mov(ApiParameterOperand(2), ebx);
2945 // Initialize FunctionCallbackInfo::values_.
2946 __ lea(ebx, MemOperand(ebx, eax, times_pointer_size,
2947 (FCA::kArgsLength - 1) * kPointerSize));
2948 __ mov(ApiParameterOperand(3), ebx);
2949 // Initialize FunctionCallbackInfo::length_.
2950 __ mov(ApiParameterOperand(4), eax);
2951
2952 // Load first argument with pointer to FunctionCallbackInfo.
2953 __ lea(ebx, ApiParameterOperand(2));
2954 __ mov(ApiParameterOperand(0), ebx);
2955
2956 ExternalReference const next_address =
2957 ExternalReference::handle_scope_next_address(masm->isolate());
2958 ExternalReference const limit_address =
2959 ExternalReference::handle_scope_limit_address(masm->isolate());
2960 ExternalReference const level_address =
2961 ExternalReference::handle_scope_level_address(masm->isolate());
2962
2963 // Allocate HandleScope in callee-save registers.
2964 __ mov(ebx, Operand::StaticVariable(next_address));
2965 __ mov(edi, Operand::StaticVariable(limit_address));
2966 __ add(Operand::StaticVariable(level_address), Immediate(1));
2967
2968 // Check if profiling is active, and if so call the function indirectly
2969 // via the invoke_function_callback helper.
2970 Label call_indirect, done_call;
2971 __ cmpb(Operand::StaticVariable(
2972 ExternalReference::is_profiling_address(masm->isolate())),
2973 Immediate(0));
2974 __ j(not_zero, &call_indirect, Label::kNear);
2975 {
2976 // Call the API function directly.
2977 __ call(edx);
2978 }
2979 __ jmp(&done_call, Label::kNear);
2980 __ bind(&call_indirect);
2981 {
2982 // Call the API function indirectly when profiling is on.
2983 __ mov(ApiParameterOperand(1), edx);
2984 __ mov(eax, Immediate(ExternalReference::invoke_function_callback(
2985 masm->isolate())));
2986 __ call(eax);
2987 }
2988 __ bind(&done_call);
2989
2990 // No more valid handles (the result handle was the last one). Restore
2991 // previous handle scope.
2992 Label delete_allocated_handles;
2993 __ mov(Operand::StaticVariable(next_address), ebx);
2994 __ sub(Operand::StaticVariable(level_address), Immediate(1));
2995 __ cmp(edi, Operand::StaticVariable(limit_address));
2996 __ j(not_equal, &delete_allocated_handles);
2997
2998 // Leave the API exit frame.
2999 Label leave_exit_frame;
3000 __ bind(&leave_exit_frame);
3001 __ mov(eax, MemOperand(ebp, (2 + FCA::kReturnValueOffset) * kPointerSize));
3002 __ mov(esi, MemOperand(ebp, (2 + FCA::kContextSaveIndex) * kPointerSize));
3003 __ mov(ebx, ApiParameterOperand(4));
3004 __ LeaveApiExitFrame(false);
3005
3006 // Check if the function scheduled an exception.
3007 Label promote_scheduled_exception;
3008 __ cmp(Operand::StaticVariable(
3009 ExternalReference::scheduled_exception_address(masm->isolate())),
3010 Immediate(masm->isolate()->factory()->the_hole_value()));
3011 __ j(not_equal, &promote_scheduled_exception);
3012
3013 // Check if the function returned a valid JavaScript value.
3014 __ AssertApiCallResult(eax);
3015
3016 // Drop the arguments and return.
3017 __ PopReturnAddressTo(ecx);
3018 __ lea(esp, MemOperand(esp, ebx, times_pointer_size,
3019 (FCA::kArgsLength + 1) * kPointerSize));
3020 __ PushReturnAddressFrom(ecx);
3021 __ Ret();
3022
3023 // Re-throw by promoting a scheduled exception.
3024 __ bind(&promote_scheduled_exception);
3025 __ TailCallRuntime(Runtime::kPromoteScheduledException);
3026
3027 // HandleScope limit has changed. Delete allocated extensions.
3028 __ bind(&delete_allocated_handles);
3029 {
3030 __ mov(Operand::StaticVariable(limit_address), edi);
3031 __ mov(Operand(esp, 0),
3032 Immediate(ExternalReference::isolate_address(masm->isolate())));
3033 __ mov(eax, Immediate(ExternalReference::delete_handle_scope_extensions(
3034 masm->isolate())));
3035 __ call(eax);
3036 }
3037 __ jmp(&leave_exit_frame);
3038 }
3039
2878 // static 3040 // static
2879 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { 3041 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2880 // ----------- S t a t e ------------- 3042 // ----------- S t a t e -------------
2881 // -- eax : the number of arguments (not including the receiver) 3043 // -- eax : the number of arguments (not including the receiver)
2882 // -- edx : the new target (checked to be a constructor) 3044 // -- edx : the new target (checked to be a constructor)
2883 // -- edi : the constructor to call (checked to be a JSFunction) 3045 // -- edi : the constructor to call (checked to be a JSFunction)
2884 // ----------------------------------- 3046 // -----------------------------------
2885 __ AssertFunction(edi); 3047 __ AssertFunction(edi);
2886 3048
2887 // Calling convention for function specific ConstructStubs require 3049 // Calling convention for function specific ConstructStubs require
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
3257 } 3419 }
3258 // Now jump to the instructions of the returned code object. 3420 // Now jump to the instructions of the returned code object.
3259 __ jmp(edi); 3421 __ jmp(edi);
3260 } 3422 }
3261 3423
3262 #undef __ 3424 #undef __
3263 } // namespace internal 3425 } // namespace internal
3264 } // namespace v8 3426 } // namespace v8
3265 3427
3266 #endif // V8_TARGET_ARCH_IA32 3428 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/builtins/builtins-definitions.h ('k') | src/builtins/mips/builtins-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698