summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/code-stubs-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/code-stubs-ia32.cc')
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.cc514
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, &not_outermost_js, Label::kNear);
- __ mov(__ StaticVariable(js_entry_sp), ebp);
- __ push(Immediate(StackFrame::OUTERMOST_JSENTRY_FRAME));
- __ jmp(&invoke, Label::kNear);
- __ bind(&not_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, &not_outermost_js_2);
- __ mov(__ StaticVariable(js_entry_sp), Immediate(0));
- __ bind(&not_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