diff options
Diffstat (limited to 'deps/v8/src/ia32/code-stubs-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/code-stubs-ia32.cc | 514 |
1 files changed, 0 insertions, 514 deletions
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc deleted file mode 100644 index 63cd5a9621..0000000000 --- a/deps/v8/src/ia32/code-stubs-ia32.cc +++ /dev/null @@ -1,514 +0,0 @@ -// Copyright 2012 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#if V8_TARGET_ARCH_IA32 - -#include "src/api-arguments-inl.h" -#include "src/assembler-inl.h" -#include "src/base/bits.h" -#include "src/bootstrapper.h" -#include "src/code-stubs.h" -#include "src/frame-constants.h" -#include "src/frames.h" -#include "src/heap/heap-inl.h" -#include "src/ic/ic.h" -#include "src/ic/stub-cache.h" -#include "src/isolate.h" -#include "src/objects/api-callbacks.h" -#include "src/regexp/jsregexp.h" -#include "src/regexp/regexp-macro-assembler.h" -#include "src/runtime/runtime.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm) - -void JSEntryStub::Generate(MacroAssembler* masm) { - Label invoke, handler_entry, exit; - Label not_outermost_js, not_outermost_js_2; - - ProfileEntryHookStub::MaybeCallEntryHook(masm); - - // Set up frame. - __ push(ebp); - __ mov(ebp, esp); - - // Push marker in two places. - StackFrame::Type marker = type(); - __ push(Immediate(StackFrame::TypeToMarker(marker))); // marker - ExternalReference context_address = - ExternalReference::Create(IsolateAddressId::kContextAddress, isolate()); - __ push(__ StaticVariable(context_address)); // context - // Save callee-saved registers (C calling conventions). - __ push(edi); - __ push(esi); - __ push(ebx); - - __ InitializeRootRegister(); - Assembler::SupportsRootRegisterScope supports_root_register(masm); - - // Save copies of the top frame descriptor on the stack. - ExternalReference c_entry_fp = - ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate()); - __ push(__ StaticVariable(c_entry_fp)); - - // If this is the outermost JS call, set js_entry_sp value. - ExternalReference js_entry_sp = - ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, isolate()); - __ cmp(__ StaticVariable(js_entry_sp), Immediate(0)); - __ j(not_equal, ¬_outermost_js, Label::kNear); - __ mov(__ StaticVariable(js_entry_sp), ebp); - __ push(Immediate(StackFrame::OUTERMOST_JSENTRY_FRAME)); - __ jmp(&invoke, Label::kNear); - __ bind(¬_outermost_js); - __ push(Immediate(StackFrame::INNER_JSENTRY_FRAME)); - - // Jump to a faked try block that does the invoke, with a faked catch - // block that sets the pending exception. - __ jmp(&invoke); - __ bind(&handler_entry); - handler_offset_ = handler_entry.pos(); - // Caught exception: Store result (exception) in the pending exception - // field in the JSEnv and return a failure sentinel. - ExternalReference pending_exception = ExternalReference::Create( - IsolateAddressId::kPendingExceptionAddress, isolate()); - __ mov(__ StaticVariable(pending_exception), eax); - __ mov(eax, Immediate(isolate()->factory()->exception())); - __ jmp(&exit); - - // Invoke: Link this frame into the handler chain. - __ bind(&invoke); - __ PushStackHandler(); - - // Invoke the function by calling through JS entry trampoline builtin and - // pop the faked function when we return. Notice that we cannot store a - // reference to the trampoline code directly in this stub, because the - // builtin stubs may not have been generated yet. - __ Call(EntryTrampoline(), RelocInfo::CODE_TARGET); - - // Unlink this frame from the handler chain. - __ PopStackHandler(); - - __ bind(&exit); - - __ VerifyRootRegister(); - - // Check if the current stack frame is marked as the outermost JS frame. - Assembler::AllowExplicitEbxAccessScope exiting_js(masm); - __ pop(ebx); - __ cmp(ebx, Immediate(StackFrame::OUTERMOST_JSENTRY_FRAME)); - __ j(not_equal, ¬_outermost_js_2); - __ mov(__ StaticVariable(js_entry_sp), Immediate(0)); - __ bind(¬_outermost_js_2); - - // Restore the top frame descriptor from the stack. - __ pop(__ StaticVariable(ExternalReference::Create( - IsolateAddressId::kCEntryFPAddress, isolate()))); - - // Restore callee-saved registers (C calling conventions). - __ pop(ebx); - __ pop(esi); - __ pop(edi); - __ add(esp, Immediate(2 * kPointerSize)); // remove markers - - // Restore frame pointer and return. - __ pop(ebp); - __ ret(0); -} - -void ProfileEntryHookStub::MaybeCallEntryHookDelayed(TurboAssembler* tasm, - Zone* zone) { - if (tasm->isolate()->function_entry_hook() != nullptr) { - tasm->CallStubDelayed(new (zone) ProfileEntryHookStub(nullptr)); - } -} - -void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { - if (masm->isolate()->function_entry_hook() != nullptr) { - ProfileEntryHookStub stub(masm->isolate()); - masm->CallStub(&stub); - } -} - - -void ProfileEntryHookStub::Generate(MacroAssembler* masm) { - Assembler::SupportsRootRegisterScope supports_root_register(masm); - - // Save volatile registers. - const int kNumSavedRegisters = 3; - __ push(eax); - __ push(ecx); - __ push(edx); - - // Calculate and push the original stack pointer. - __ lea(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize)); - __ push(eax); - - // Retrieve our return address and use it to calculate the calling - // function's address. - __ mov(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize)); - __ sub(eax, Immediate(Assembler::kCallInstructionLength)); - __ push(eax); - - // Call the entry hook. - DCHECK_NOT_NULL(isolate()->function_entry_hook()); - __ call(FUNCTION_ADDR(isolate()->function_entry_hook()), - RelocInfo::RUNTIME_ENTRY); - __ add(esp, Immediate(2 * kPointerSize)); - - // Restore ecx. - __ pop(edx); - __ pop(ecx); - __ pop(eax); - - __ ret(0); -} - -// Generates an Operand for saving parameters after PrepareCallApiFunction. -static Operand ApiParameterOperand(int index) { - return Operand(esp, index * kPointerSize); -} - - -// Prepares stack to put arguments (aligns and so on). Reserves -// space for return value if needed (assumes the return value is a handle). -// Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1) -// etc. Saves context (esi). If space was reserved for return value then -// stores the pointer to the reserved slot into esi. -static void PrepareCallApiFunction(MacroAssembler* masm, int argc) { - __ EnterApiExitFrame(argc); - if (__ emit_debug_code()) { - __ mov(esi, Immediate(bit_cast<int32_t>(kZapValue))); - } -} - -// Calls an API function. Allocates HandleScope, extracts returned value -// from handle and propagates exceptions. Clobbers esi, edi and -// caller-save registers. Restores context. On return removes -// stack_space * kPointerSize (GCed). -static void CallApiFunctionAndReturn(MacroAssembler* masm, - Register function_address, - ExternalReference thunk_ref, - Operand thunk_last_arg, int stack_space, - Operand* stack_space_operand, - Operand return_value_operand) { - Assembler::SupportsRootRegisterScope supports_root_register(masm); - Isolate* isolate = masm->isolate(); - - ExternalReference next_address = - ExternalReference::handle_scope_next_address(isolate); - ExternalReference limit_address = - ExternalReference::handle_scope_limit_address(isolate); - ExternalReference level_address = - ExternalReference::handle_scope_level_address(isolate); - - DCHECK(edx == function_address); - // Allocate HandleScope in callee-save registers. - __ mov(esi, __ StaticVariable(next_address)); - __ mov(edi, __ StaticVariable(limit_address)); - __ add(__ StaticVariable(level_address), Immediate(1)); - - if (FLAG_log_timer_events) { - FrameScope frame(masm, StackFrame::MANUAL); - __ PushSafepointRegisters(); - __ PrepareCallCFunction(1, eax); - __ mov(Operand(esp, 0), - Immediate(ExternalReference::isolate_address(isolate))); - __ CallCFunction(ExternalReference::log_enter_external_function(), 1); - __ PopSafepointRegisters(); - } - - - Label profiler_disabled; - Label end_profiler_check; - __ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate))); - __ cmpb(Operand(eax, 0), Immediate(0)); - __ j(zero, &profiler_disabled); - - // Additional parameter is the address of the actual getter function. - __ mov(thunk_last_arg, function_address); - // Call the api function. - __ mov(eax, Immediate(thunk_ref)); - __ call(eax); - __ jmp(&end_profiler_check); - - __ bind(&profiler_disabled); - // Call the api function. - __ call(function_address); - __ bind(&end_profiler_check); - - if (FLAG_log_timer_events) { - FrameScope frame(masm, StackFrame::MANUAL); - __ PushSafepointRegisters(); - __ PrepareCallCFunction(1, eax); - __ mov(Operand(esp, 0), - Immediate(ExternalReference::isolate_address(isolate))); - __ CallCFunction(ExternalReference::log_leave_external_function(), 1); - __ PopSafepointRegisters(); - } - - Label prologue; - // Load the value from ReturnValue - __ mov(eax, return_value_operand); - - Label promote_scheduled_exception; - Label delete_allocated_handles; - Label leave_exit_frame; - - __ bind(&prologue); - // No more valid handles (the result handle was the last one). Restore - // previous handle scope. - __ mov(__ StaticVariable(next_address), esi); - __ sub(__ StaticVariable(level_address), Immediate(1)); - __ Assert(above_equal, AbortReason::kInvalidHandleScopeLevel); - __ cmp(edi, __ StaticVariable(limit_address)); - __ j(not_equal, &delete_allocated_handles); - - // Leave the API exit frame. - __ bind(&leave_exit_frame); - if (stack_space_operand != nullptr) { - __ mov(edx, *stack_space_operand); - } - __ LeaveApiExitFrame(); - - // Check if the function scheduled an exception. - ExternalReference scheduled_exception_address = - ExternalReference::scheduled_exception_address(isolate); - __ cmp(__ StaticVariable(scheduled_exception_address), - Immediate(isolate->factory()->the_hole_value())); - __ j(not_equal, &promote_scheduled_exception); - -#if DEBUG - // Check if the function returned a valid JavaScript value. - Label ok; - Register return_value = eax; - Register map = ecx; - - __ JumpIfSmi(return_value, &ok, Label::kNear); - __ mov(map, FieldOperand(return_value, HeapObject::kMapOffset)); - - __ CmpInstanceType(map, LAST_NAME_TYPE); - __ j(below_equal, &ok, Label::kNear); - - __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); - __ j(above_equal, &ok, Label::kNear); - - __ cmp(map, isolate->factory()->heap_number_map()); - __ j(equal, &ok, Label::kNear); - - __ cmp(return_value, isolate->factory()->undefined_value()); - __ j(equal, &ok, Label::kNear); - - __ cmp(return_value, isolate->factory()->true_value()); - __ j(equal, &ok, Label::kNear); - - __ cmp(return_value, isolate->factory()->false_value()); - __ j(equal, &ok, Label::kNear); - - __ cmp(return_value, isolate->factory()->null_value()); - __ j(equal, &ok, Label::kNear); - - __ Abort(AbortReason::kAPICallReturnedInvalidObject); - - __ bind(&ok); -#endif - - if (stack_space_operand != nullptr) { - DCHECK_EQ(0, stack_space); - __ pop(ecx); - __ add(esp, edx); - __ jmp(ecx); - } else { - __ ret(stack_space * kPointerSize); - } - - // Re-throw by promoting a scheduled exception. - __ bind(&promote_scheduled_exception); - __ TailCallRuntime(Runtime::kPromoteScheduledException); - - // HandleScope limit has changed. Delete allocated extensions. - ExternalReference delete_extensions = - ExternalReference::delete_handle_scope_extensions(); - __ bind(&delete_allocated_handles); - __ mov(__ StaticVariable(limit_address), edi); - __ mov(edi, eax); - __ mov(Operand(esp, 0), - Immediate(ExternalReference::isolate_address(isolate))); - __ mov(eax, Immediate(delete_extensions)); - __ call(eax); - __ mov(eax, edi); - __ jmp(&leave_exit_frame); -} - -void CallApiCallbackStub::Generate(MacroAssembler* masm) { - Assembler::SupportsRootRegisterScope supports_root_register(masm); - - // ----------- S t a t e ------------- - // -- eax : call_data - // -- ecx : holder - // -- edx : api_function_address - // -- esi : context - // -- - // -- esp[0] : return address - // -- esp[4] : last argument - // -- ... - // -- esp[argc * 4] : first argument - // -- esp[(argc + 1) * 4] : receiver - // ----------------------------------- - - Register call_data = eax; - Register holder = ecx; - Register api_function_address = edx; - Register return_address = edi; - - typedef FunctionCallbackArguments FCA; - - STATIC_ASSERT(FCA::kArgsLength == 6); - STATIC_ASSERT(FCA::kNewTargetIndex == 5); - STATIC_ASSERT(FCA::kDataIndex == 4); - STATIC_ASSERT(FCA::kReturnValueOffset == 3); - STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); - STATIC_ASSERT(FCA::kIsolateIndex == 1); - STATIC_ASSERT(FCA::kHolderIndex == 0); - - __ pop(return_address); - - // new target - __ PushRoot(RootIndex::kUndefinedValue); - - // call data - __ push(call_data); - - // return value - __ PushRoot(RootIndex::kUndefinedValue); - // return value default - __ PushRoot(RootIndex::kUndefinedValue); - // isolate - __ push(Immediate(ExternalReference::isolate_address(isolate()))); - // holder - __ push(holder); - - Register scratch = call_data; - - __ mov(scratch, esp); - - // push return address - __ push(return_address); - - // API function gets reference to the v8::Arguments. If CPU profiler - // is enabled wrapper function will be called and we need to pass - // address of the callback as additional parameter, always allocate - // space for it. - const int kApiArgc = 1 + 1; - - // Allocate the v8::Arguments structure in the arguments' space since - // it's not controlled by GC. - const int kApiStackSpace = 3; - - PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace); - - // FunctionCallbackInfo::implicit_args_. - __ mov(ApiParameterOperand(2), scratch); - __ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize)); - // FunctionCallbackInfo::values_. - __ mov(ApiParameterOperand(3), scratch); - // FunctionCallbackInfo::length_. - __ Move(ApiParameterOperand(4), Immediate(argc())); - - // v8::InvocationCallback's argument. - __ lea(scratch, ApiParameterOperand(2)); - __ mov(ApiParameterOperand(0), scratch); - - ExternalReference thunk_ref = ExternalReference::invoke_function_callback(); - - // Stores return the first js argument - int return_value_offset = 2 + FCA::kReturnValueOffset; - Operand return_value_operand(ebp, return_value_offset * kPointerSize); - const int stack_space = argc() + FCA::kArgsLength + 1; - Operand* stack_space_operand = nullptr; - CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, - ApiParameterOperand(1), stack_space, - stack_space_operand, return_value_operand); -} - - -void CallApiGetterStub::Generate(MacroAssembler* masm) { - Assembler::SupportsRootRegisterScope supports_root_register(masm); - - // Build v8::PropertyCallbackInfo::args_ array on the stack and push property - // name below the exit frame to make GC aware of them. - STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0); - STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1); - STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2); - STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3); - STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4); - STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5); - STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6); - STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7); - - Register receiver = ApiGetterDescriptor::ReceiverRegister(); - Register holder = ApiGetterDescriptor::HolderRegister(); - Register callback = ApiGetterDescriptor::CallbackRegister(); - Register scratch = edi; - DCHECK(!AreAliased(receiver, holder, callback, scratch)); - - __ pop(scratch); // Pop return address to extend the frame. - __ push(receiver); - __ push(FieldOperand(callback, AccessorInfo::kDataOffset)); - __ PushRoot(RootIndex::kUndefinedValue); // ReturnValue - // ReturnValue default value - __ PushRoot(RootIndex::kUndefinedValue); - __ push(Immediate(ExternalReference::isolate_address(isolate()))); - __ push(holder); - __ push(Immediate(Smi::kZero)); // should_throw_on_error -> false - __ push(FieldOperand(callback, AccessorInfo::kNameOffset)); - __ push(scratch); // Restore return address. - - // v8::PropertyCallbackInfo::args_ array and name handle. - const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; - - // Allocate v8::PropertyCallbackInfo object, arguments for callback and - // space for optional callback address parameter (in case CPU profiler is - // active) in non-GCed stack space. - const int kApiArgc = 3 + 1; - - // Load address of v8::PropertyAccessorInfo::args_ array. - __ lea(scratch, Operand(esp, 2 * kPointerSize)); - - PrepareCallApiFunction(masm, kApiArgc); - // Create v8::PropertyCallbackInfo object on the stack and initialize - // it's args_ field. - Operand info_object = ApiParameterOperand(3); - __ mov(info_object, scratch); - - // Name as handle. - __ sub(scratch, Immediate(kPointerSize)); - __ mov(ApiParameterOperand(0), scratch); - // Arguments pointer. - __ lea(scratch, info_object); - __ mov(ApiParameterOperand(1), scratch); - // Reserve space for optional callback address parameter. - Operand thunk_last_arg = ApiParameterOperand(2); - - ExternalReference thunk_ref = - ExternalReference::invoke_accessor_getter_callback(); - - __ mov(scratch, FieldOperand(callback, AccessorInfo::kJsGetterOffset)); - Register function_address = edx; - __ mov(function_address, - FieldOperand(scratch, Foreign::kForeignAddressOffset)); - // +3 is to skip prolog, return address and name handle. - Operand return_value_operand( - ebp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize); - CallApiFunctionAndReturn(masm, function_address, thunk_ref, thunk_last_arg, - kStackUnwindSpace, nullptr, return_value_operand); -} - -#undef __ - -} // namespace internal -} // namespace v8 - -#endif // V8_TARGET_ARCH_IA32 |