descriptor->register_params_ = registers;
descriptor->param_representations_ = representations;
}
+ {
+ CallInterfaceDescriptor* descriptor =
+ isolate->call_descriptor(Isolate::ApiFunctionCall);
+ static Register registers[] = { a0, // callee
+ t0, // call_data
+ a2, // holder
+ a1, // api_function_address
+ cp, // context
+ };
+ static Representation representations[] = {
+ Representation::Tagged(), // callee
+ Representation::Tagged(), // call_data
+ Representation::Tagged(), // holder
+ Representation::External(), // api_function_address
+ Representation::Tagged(), // context
+ };
+ descriptor->register_param_count_ = 5;
+ descriptor->register_params_ = registers;
+ descriptor->param_representations_ = representations;
+ }
}
// -- a0 : callee
// -- t0 : call_data
// -- a2 : holder
- // -- a3 : api_function_address
- // -- a1 : thunk_arg
+ // -- a1 : api_function_address
// -- cp : context
// --
// -- sp[0] : last argument
Register callee = a0;
Register call_data = t0;
Register holder = a2;
- Register api_function_address = a3;
- Register thunk_arg = a1;
+ Register api_function_address = a1;
Register context = cp;
int argc = ArgumentBits::decode(bit_field_);
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
- ASSERT(!thunk_arg.is(a0) && !api_function_address.is(a0) && !scratch.is(a0));
+ ASSERT(!api_function_address.is(a0) && !scratch.is(a0));
// a0 = FunctionCallbackInfo&
// Arguments is after the return address.
__ Addu(a0, sp, Operand(1 * kPointerSize));
__ CallApiFunctionAndReturn(api_function_address,
thunk_ref,
- thunk_arg,
kStackUnwindSpace,
return_value_operand,
restore_context ?
// -- sp[0] : name
// -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
- // -- a3 : api_function_address
- // -- a2 : thunk_last_arg
+ // -- a2 : api_function_address
// -----------------------------------
- Register api_function_address = a3;
- Register thunk_last_arg = a2;
+ Register api_function_address = a2;
__ mov(a0, sp); // a0 = Handle<Name>
__ Addu(a1, a0, Operand(1 * kPointerSize)); // a1 = PCA
masm->isolate());
__ CallApiFunctionAndReturn(api_function_address,
thunk_ref,
- thunk_last_arg,
kStackUnwindSpace,
MemOperand(fp, 6 * kPointerSize),
NULL);
return reinterpret_cast<Redirection*>(addr_of_redirection);
}
+ static void* ReverseRedirection(int32_t reg) {
+ Redirection* redirection = FromSwiInstruction(
+ reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
+ return redirection->external_function();
+ }
+
private:
void* external_function_;
uint32_t swi_instruction_;
// This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h).
typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
-typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, void* arg1);
// This signature supports direct call to accessor getter callback.
typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
typedef void (*SimulatorRuntimeProfilingGetterCall)(
- int32_t arg0, int32_t arg1, int32_t arg2);
+ int32_t arg0, int32_t arg1, void* arg2);
// Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime. They are also used for debugging with simulator.
}
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
- target(arg0, arg1);
+ target(arg0, Redirection::ReverseRedirection(arg1));
} else if (
redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim) {
}
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
- target(arg0, arg1, arg2);
+ target(arg0, arg1, Redirection::ReverseRedirection(arg2));
} else {
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
Register callee = a0;
Register call_data = t0;
Register holder = a2;
- Register api_function_address = a3;
- Register thunk_arg = a1;
+ Register api_function_address = a1;
// Put holder in place.
__ mov(holder, holder_in);
type,
masm->isolate());
__ li(api_function_address, Operand(ref));
- __ li(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
// Jump to stub.
CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
}
-// Generates call to API function.
-static void GenerateFastApiCall(MacroAssembler* masm,
- const CallOptimization& optimization,
- int argc,
- Handle<Map> map_to_holder,
- CallOptimization::HolderLookup holder_lookup) {
- Counters* counters = masm->isolate()->counters();
- __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1);
-
- // Move holder to a register.
- Register holder_reg = a2;
- switch (holder_lookup) {
- case CallOptimization::kHolderIsReceiver:
- {
- ASSERT(map_to_holder.is_null());
- __ lw(holder_reg, MemOperand(sp, argc * kPointerSize));
- }
- break;
- case CallOptimization::kHolderIsPrototypeOfMap:
- {
- Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype()));
- if (!masm->isolate()->heap()->InNewSpace(*holder)) {
- __ li(holder_reg, holder);
- } else {
- __ li(holder_reg, map_to_holder);
- __ lw(holder_reg,
- FieldMemOperand(holder_reg, Map::kPrototypeOffset));
- }
- }
- break;
- case CallOptimization::kHolderNotFound:
- UNREACHABLE();
- }
- GenerateFastApiCallBody(masm,
- optimization,
- argc,
- holder_reg,
- false);
-}
-
-
// Generate call to api function.
static void GenerateFastApiCall(MacroAssembler* masm,
const CallOptimization& optimization,
name, miss_label);
}
- Handle<Map> lookup_map;
- CallOptimization::HolderLookup holder_lookup =
- CallOptimization::kHolderNotFound;
- if (optimization.is_simple_api_call() &&
- !lookup->holder()->IsGlobalObject()) {
- lookup_map = optimization.LookupHolderOfExpectedType(
- object, object, interceptor_holder, &holder_lookup);
- if (holder_lookup == CallOptimization::kHolderNotFound) {
- lookup_map =
- optimization.LookupHolderOfExpectedType(
- object,
- interceptor_holder,
- Handle<JSObject>(lookup->holder()),
- &holder_lookup);
- }
- }
-
- // Invoke function.
- if (holder_lookup != CallOptimization::kHolderNotFound) {
- int argc = arguments_.immediate();
- GenerateFastApiCall(masm,
- optimization,
- argc,
- lookup_map,
- holder_lookup);
- } else {
- Handle<JSFunction> function = optimization.constant_function();
- __ Move(a0, receiver);
- stub_compiler_->GenerateJumpFunction(object, function);
- }
+ Handle<JSFunction> function = optimization.constant_function();
+ __ Move(a0, receiver);
+ stub_compiler_->GenerateJumpFunction(object, function);
// Invoke a regular function.
__ bind(®ular_invoke);
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
// Abi for CallApiGetter.
- Register getter_address_reg = a3;
- Register thunk_last_arg = a2;
+ Register getter_address_reg = a2;
Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address);
ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
ExternalReference ref = ExternalReference(&fun, type, isolate());
__ li(getter_address_reg, Operand(ref));
- __ li(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
CallApiGetterStub stub;
__ TailCallStub(&stub);
}
-Handle<Code> CallStubCompiler::CompileFastApiCall(
- const CallOptimization& optimization,
- Handle<Object> object,
- Handle<JSObject> holder,
- Handle<Cell> cell,
- Handle<JSFunction> function,
- Handle<String> name) {
-
- Counters* counters = isolate()->counters();
-
- ASSERT(optimization.is_simple_api_call());
- // Bail out if object is a global object as we don't want to
- // repatch it to global receiver.
- if (object->IsGlobalObject()) return Handle<Code>::null();
- if (!cell.is_null()) return Handle<Code>::null();
- if (!object->IsJSObject()) return Handle<Code>::null();
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
- CallOptimization::HolderLookup holder_lookup =
- CallOptimization::kHolderNotFound;
- Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType(
- receiver, receiver, holder, &holder_lookup);
- if (holder_lookup == CallOptimization::kHolderNotFound) {
- return Handle<Code>::null();
- }
-
- Label miss;
- GenerateNameCheck(name, &miss);
-
- // Get the receiver from the stack.
- const int argc = arguments().immediate();
- __ lw(a1, MemOperand(sp, argc * kPointerSize));
-
- // Check that the receiver isn't a smi.
- __ JumpIfSmi(a1, &miss);
-
- __ IncrementCounter(counters->call_const(), 1, a0, a3);
-
- // Check that the maps haven't changed and find a Holder as a side effect.
- CheckPrototypes(
- IC::CurrentTypeOf(object, isolate()),
- a1, holder, a0, a3, t0, name, &miss);
-
- GenerateFastApiCall(
- masm(), optimization, argc, lookup_map, holder_lookup);
-
- HandlerFrontendFooter(&miss);
-
- // Return the generated code.
- return GetCode(function);
-}
-
-
void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
Label success;
// Check that the object is a boolean.
Handle<PropertyCell> cell,
Handle<JSFunction> function,
Handle<Name> name) {
- if (HasCustomCallGenerator(function)) {
- Handle<Code> code = CompileCustomCall(
- object, holder, cell, function, Handle<String>::cast(name),
- Code::NORMAL);
- // A null handle means bail out to the regular compiler code below.
- if (!code.is_null()) return code;
- }
-
Label miss;
HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
// Potentially loads a closure that matches the shared function info of the