}
+v8::Handle<v8::Value> InvokeAccessorGetter(
+ v8::Local<v8::String> property,
+ const v8::AccessorInfo& info,
+ v8::AccessorGetter getter) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
+ Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
+ getter));
+ // Leaving JavaScript.
+ VMState<EXTERNAL> state(isolate);
+ ExternalCallbackScope call_scope(isolate, getter_address);
+ return getter(property, info);
+}
+
+
+void InvokeAccessorGetterCallback(
+ v8::Local<v8::String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info,
+ v8::AccessorGetterCallback getter) {
+ // Leaving JavaScript.
+ Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
+ Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
+ getter));
+ VMState<EXTERNAL> state(isolate);
+ ExternalCallbackScope call_scope(isolate, getter_address);
+ return getter(property, info);
+}
+
+
+v8::Handle<v8::Value> InvokeInvocationCallback(
+ const v8::Arguments& args,
+ v8::InvocationCallback callback) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(args.GetIsolate());
+ Address callback_address =
+ reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
+ VMState<EXTERNAL> state(isolate);
+ ExternalCallbackScope call_scope(isolate, callback_address);
+ return callback(args);
+}
+
+
+void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
+ v8::FunctionCallback callback) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
+ Address callback_address =
+ reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
+ VMState<EXTERNAL> state(isolate);
+ ExternalCallbackScope call_scope(isolate, callback_address);
+ return callback(info);
+}
+
+
} } // namespace v8::internal
}
+// Interceptor functions called from generated inline caches to notify
+// CPU profiler that external callbacks are invoked.
+v8::Handle<v8::Value> InvokeAccessorGetter(
+ v8::Local<v8::String> property,
+ const v8::AccessorInfo& info,
+ v8::AccessorGetter getter);
+
+
+void InvokeAccessorGetterCallback(
+ v8::Local<v8::String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info,
+ v8::AccessorGetterCallback getter);
+
+v8::Handle<v8::Value> InvokeInvocationCallback(const v8::Arguments& args,
+ v8::InvocationCallback callback);
+void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
+ v8::FunctionCallback callback);
+
class Testing {
public:
static v8::Testing::StressType stress_type() { return stress_type_; }
}
-void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
- ExternalReference function) {
- __ mov(r2, Operand(function));
- GenerateCall(masm, r2);
-}
-
-
void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
Register target) {
intptr_t code =
public:
DirectCEntryStub() {}
void Generate(MacroAssembler* masm);
- void GenerateCall(MacroAssembler* masm, ExternalReference function);
void GenerateCall(MacroAssembler* masm, Register target);
private:
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
+ Address function_address,
+ ExternalReference thunk_ref,
+ Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset) {
PopSafepointRegisters();
}
+ ASSERT(!thunk_last_arg.is(r3));
+ Label profiler_disabled;
+ Label end_profiler_check;
+ bool* is_profiling_flag =
+ isolate()->cpu_profiler()->is_profiling_address();
+ STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
+ mov(r3, Operand(reinterpret_cast<int32_t>(is_profiling_flag)));
+ ldrb(r3, MemOperand(r3, 0));
+ cmp(r3, Operand(0));
+ b(eq, &profiler_disabled);
+
+ // Additional parameter is the address of the actual callback.
+ mov(thunk_last_arg, Operand(reinterpret_cast<int32_t>(function_address)));
+ mov(r3, Operand(thunk_ref));
+ jmp(&end_profiler_check);
+
+ bind(&profiler_disabled);
+ mov(r3, Operand(function));
+ bind(&end_profiler_check);
+
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
DirectCEntryStub stub;
- stub.GenerateCall(this, function);
+ stub.GenerateCall(this, r3);
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
// - space to be unwound on exit (includes the call JS arguments space and
// the additional space allocated for the fast call).
void CallApiFunctionAndReturn(ExternalReference function,
+ Address function_address,
+ ExternalReference thunk_ref,
+ Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp);
Isolate* isolate = Isolate::Current();
Redirection* current = isolate->simulator_redirection();
for (; current != NULL; current = current->next_) {
- if (current->external_function_ == external_function) return current;
+ if (current->external_function_ == external_function) {
+ ASSERT_EQ(current->type(), type);
+ return current;
+ }
}
return new Redirection(external_function, type);
}
// (refer to InvocationCallback in v8.h).
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
+typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
+ int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback.
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
int32_t arg1);
typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
int32_t arg1);
+typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
+ int32_t arg0, int32_t arg1, int32_t arg2);
+typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
+ int32_t arg0, int32_t arg1, int32_t arg2);
// Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime.
reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
target(arg0);
}
+ } else if (
+ redirection->type() == ExternalReference::PROFILING_API_CALL ||
+ redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
+ if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+ PrintF("Call to host function at %p args %08x %08x",
+ reinterpret_cast<void*>(external), arg0, arg1);
+ if (!stack_aligned) {
+ PrintF(" with unaligned stack %08x\n", get_register(sp));
+ }
+ PrintF("\n");
+ }
+ CHECK(stack_aligned);
+ if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
+ SimulatorRuntimeProfilingApiCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+ v8::Handle<v8::Value> result = target(arg0, arg1);
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
+ }
+ set_register(r0, reinterpret_cast<int32_t>(*result));
+ } else {
+ SimulatorRuntimeProfilingApiCallNew target =
+ reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
+ target(arg0, arg1);
+ }
} else if (
redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
target(arg0, arg1);
}
+ } else if (
+ redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
+ redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
+ if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+ PrintF("Call to host function at %p args %08x %08x %08x",
+ reinterpret_cast<void*>(external), arg0, arg1, arg2);
+ if (!stack_aligned) {
+ PrintF(" with unaligned stack %08x\n", get_register(sp));
+ }
+ PrintF("\n");
+ }
+ CHECK(stack_aligned);
+ if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
+ SimulatorRuntimeProfilingGetterCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
+ v8::Handle<v8::Value> result = target(arg0, arg1, arg2);
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
+ }
+ set_register(r0, reinterpret_cast<int32_t>(*result));
+ } else {
+ SimulatorRuntimeProfilingGetterCallNew target =
+ reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(
+ external);
+ target(arg0, arg1, arg2);
+ }
} else {
// builtin call.
ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
reinterpret_cast<SimulatorRuntimeCall>(external);
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF(
- "Call to host function at %p"
+ "Call to host function at %p "
"args %08x, %08x, %08x, %08x, %08x, %08x",
FUNCTION_ADDR(target),
arg0,
ExternalReference ref = ExternalReference(&fun,
type,
masm->isolate());
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeInvocationCallback)
+ : FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference::Type thunk_type =
+ returns_handle ?
+ ExternalReference::PROFILING_API_CALL :
+ ExternalReference::PROFILING_API_CALL_NEW;
+ ApiFunction thunk_fun(thunk_address);
+ ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+ masm->isolate());
+
AllowExternalCallThatCantCauseGC scope(masm);
__ CallApiFunctionAndReturn(ref,
+ function_address,
+ thunk_ref,
+ r1,
kStackUnwindSpace,
returns_handle,
kFastApiCallArguments + 1);
Address getter_address = v8::ToCData<Address>(callback->getter());
bool returns_handle =
!CallbackTable::ReturnsVoid(isolate(), getter_address);
+
ApiFunction fun(getter_address);
ExternalReference::Type type =
returns_handle ?
ExternalReference::DIRECT_GETTER_CALL :
ExternalReference::DIRECT_GETTER_CALL_NEW;
-
ExternalReference ref = ExternalReference(&fun, type, isolate());
+
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeAccessorGetter)
+ : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ ExternalReference::Type thunk_type =
+ returns_handle ?
+ ExternalReference::PROFILING_GETTER_CALL :
+ ExternalReference::PROFILING_GETTER_CALL_NEW;
+ ApiFunction thunk_fun(thunk_address);
+ ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+ isolate());
__ CallApiFunctionAndReturn(ref,
+ getter_address,
+ thunk_ref,
+ r2,
kStackUnwindSpace,
returns_handle,
5);
// Handle<Value> f(v8::Arguments&)
DIRECT_API_CALL,
+ // Call to invocation callback via InvokeInvocationCallback.
+ // Handle<Value> f(v8::Arguments&, v8::InvocationCallback)
+ PROFILING_API_CALL,
+
// Direct call to API function callback.
// void f(v8::Arguments&)
DIRECT_API_CALL_NEW,
+ // Call to function callback via InvokeFunctionCallback.
+ // void f(v8::Arguments&, v8::FunctionCallback)
+ PROFILING_API_CALL_NEW,
+
// Direct call to accessor getter callback.
// Handle<value> f(Local<String> property, AccessorInfo& info)
DIRECT_GETTER_CALL,
+ // Call to accessor getter callback via InvokeAccessorGetter.
+ // Handle<value> f(Local<String> property, AccessorInfo& info,
+ // AccessorGetter getter)
+ PROFILING_GETTER_CALL,
+
// Direct call to accessor getter callback.
// void f(Local<String> property, AccessorInfo& info)
- DIRECT_GETTER_CALL_NEW
+ DIRECT_GETTER_CALL_NEW,
+
+ // Call to accessor getter callback via InvokeAccessorGetterCallback.
+ // void f(Local<String> property, AccessorInfo& info,
+ // AccessorGetterCallback callback)
+ PROFILING_GETTER_CALL_NEW
};
static void SetUp();
void SharedFunctionInfoMoveEvent(Address from, Address to);
INLINE(bool is_profiling() const) { return is_profiling_; }
+ bool* is_profiling_address() {
+ return &is_profiling_;
+ }
private:
void StartProcessorIfNotStarted();
void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
+ Address thunk_address,
+ Operand thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset) {
PopSafepointRegisters();
}
+
+ Label profiler_disabled;
+ Label end_profiler_check;
+ bool* is_profiling_flag =
+ isolate()->cpu_profiler()->is_profiling_address();
+ STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
+ mov(eax, Immediate(reinterpret_cast<Address>(is_profiling_flag)));
+ cmpb(Operand(eax, 0), 0);
+ j(zero, &profiler_disabled);
+
+ // Additional parameter is the address of the actual getter function.
+ mov(thunk_last_arg, Immediate(function_address));
+ // Call the api function.
+ call(thunk_address, RelocInfo::RUNTIME_ENTRY);
+ jmp(&end_profiler_check);
+
+ bind(&profiler_disabled);
// Call the api function.
call(function_address, RelocInfo::RUNTIME_ENTRY);
+ bind(&end_profiler_check);
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
void CallApiFunctionAndReturn(Address function_address,
+ Address thunk_address,
+ Operand thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_ebp);
STATIC_ASSERT(kFastApiCallArguments == 6);
__ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
- const int kApiArgc = 1; // API function gets reference to the v8::Arguments.
+
+ // 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.
__ PrepareCallApiFunction(kApiArgc + kApiStackSpace, returns_handle);
// v8::Arguments::implicit_args_.
- __ mov(ApiParameterOperand(1, returns_handle), eax);
+ __ mov(ApiParameterOperand(2, returns_handle), eax);
__ add(eax, Immediate(argc * kPointerSize));
// v8::Arguments::values_.
- __ mov(ApiParameterOperand(2, returns_handle), eax);
+ __ mov(ApiParameterOperand(3, returns_handle), eax);
// v8::Arguments::length_.
- __ Set(ApiParameterOperand(3, returns_handle), Immediate(argc));
+ __ Set(ApiParameterOperand(4, returns_handle), Immediate(argc));
// v8::Arguments::is_construct_call_.
- __ Set(ApiParameterOperand(4, returns_handle), Immediate(0));
+ __ Set(ApiParameterOperand(5, returns_handle), Immediate(0));
// v8::InvocationCallback's argument.
- __ lea(eax, ApiParameterOperand(1, returns_handle));
+ __ lea(eax, ApiParameterOperand(2, returns_handle));
__ mov(ApiParameterOperand(0, returns_handle), eax);
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeInvocationCallback)
+ : FUNCTION_ADDR(&InvokeFunctionCallback);
+
__ CallApiFunctionAndReturn(function_address,
+ thunk_address,
+ ApiParameterOperand(1, returns_handle),
argc + kFastApiCallArguments + 1,
returns_handle,
kFastApiCallArguments + 1);
// array for v8::Arguments::values_, handler for name and pointer
// to the values (it considered as smi in GC).
const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2;
- const int kApiArgc = 2;
+ // Allocate space for opional callback address parameter in case
+ // CPU profiler is active.
+ const int kApiArgc = 2 + 1;
Address getter_address = v8::ToCData<Address>(callback->getter());
bool returns_handle =
// garbage collection but instead return the allocation failure
// object.
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeAccessorGetter)
+ : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+
__ CallApiFunctionAndReturn(getter_address,
+ thunk_address,
+ ApiParameterOperand(2, returns_handle),
kStackSpace,
returns_handle,
6);
}
-void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
- ExternalReference function) {
- __ li(t9, Operand(function));
- this->GenerateCall(masm, t9);
-}
-
-
void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
Register target) {
__ Move(t9, target);
public:
DirectCEntryStub() {}
void Generate(MacroAssembler* masm);
- void GenerateCall(MacroAssembler* masm,
- ExternalReference function);
void GenerateCall(MacroAssembler* masm, Register target);
private:
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
+ Address function_address,
+ ExternalReference thunk_ref,
+ Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp) {
addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
}
+ Label profiler_disabled;
+ Label end_profiler_check;
+ bool* is_profiling_flag =
+ isolate()->cpu_profiler()->is_profiling_address();
+ STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
+ li(t9, reinterpret_cast<int32_t>(is_profiling_flag));
+ lb(t9, MemOperand(t9, 0));
+ beq(t9, zero_reg, &profiler_disabled);
+
+ // Third parameter is the address of the actual getter function.
+ li(thunk_last_arg, reinterpret_cast<int32_t>(function_address));
+ li(t9, Operand(thunk_ref));
+ jmp(&end_profiler_check);
+
+ bind(&profiler_disabled);
+ li(t9, Operand(function));
+
+ bind(&end_profiler_check);
+
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
DirectCEntryStub stub;
- stub.GenerateCall(this, function);
+ stub.GenerateCall(this, t9);
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
// - space to be unwound on exit (includes the call JS arguments space and
// the additional space allocated for the fast call).
void CallApiFunctionAndReturn(ExternalReference function,
+ Address function_address,
+ ExternalReference thunk_ref,
+ Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp);
// Here, we pass the first argument in a0, because this function
// does not return a struct.
typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
+typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
+ int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback.
// See comment at SimulatorRuntimeDirectApiCall.
// See comment at SimulatorRuntimeDirectApiCallNew.
typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
int32_t arg1);
+typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
+ int32_t arg0, int32_t arg1, int32_t arg2);
+typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
+ int32_t arg0, int32_t arg1, int32_t 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.
reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
target(arg0);
}
+ } else if (
+ redirection->type() == ExternalReference::PROFILING_API_CALL ||
+ redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
+ if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
+ // See comment at type definition of SimulatorRuntimeDirectApiCall
+ // for explanation of register usage.
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x\n",
+ reinterpret_cast<void*>(external), arg1, arg2);
+ }
+ SimulatorRuntimeProfilingApiCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+ v8::Handle<v8::Value> result = target(arg1, arg2);
+ *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
+ set_register(v0, arg0);
+ } else {
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x\n",
+ reinterpret_cast<void*>(external), arg0, arg1);
+ }
+ SimulatorRuntimeProfilingApiCallNew target =
+ reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
+ target(arg0, arg1);
+ }
} else if (
redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
target(arg0, arg1);
}
+ } else if (
+ redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
+ redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
+ if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
+ // See comment at type definition of SimulatorRuntimeProfilingGetterCall
+ // for explanation of register usage.
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x %08x\n",
+ reinterpret_cast<void*>(external), arg1, arg2, arg3);
+ }
+ SimulatorRuntimeProfilingGetterCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
+ v8::Handle<v8::Value> result = target(arg1, arg2, arg3);
+ *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
+ set_register(v0, arg0);
+ } else {
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x %08x\n",
+ reinterpret_cast<void*>(external), arg0, arg1, arg2);
+ }
+ SimulatorRuntimeProfilingGetterCallNew target =
+ reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(external);
+ target(arg0, arg1, arg2);
+ }
} else {
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
!CallbackTable::ReturnsVoid(masm->isolate(), function_address);
Register first_arg = returns_handle ? a1 : a0;
+ Register second_arg = returns_handle ? a2 : a1;
// first_arg = v8::Arguments&
// Arguments is built at sp + 1 (sp is a reserved spot for ra).
ExternalReference(&fun,
type,
masm->isolate());
+
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeInvocationCallback)
+ : FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference::Type thunk_type =
+ returns_handle ?
+ ExternalReference::PROFILING_API_CALL :
+ ExternalReference::PROFILING_API_CALL_NEW;
+ ApiFunction thunk_fun(thunk_address);
+ ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+ masm->isolate());
+
AllowExternalCallThatCantCauseGC scope(masm);
__ CallApiFunctionAndReturn(ref,
+ function_address,
+ thunk_ref,
+ second_arg,
kStackUnwindSpace,
returns_handle,
kFastApiCallArguments + 1);
Register first_arg = returns_handle ? a1 : a0;
Register second_arg = returns_handle ? a2 : a1;
+ Register third_arg = returns_handle ? a3 : a2;
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
__ mov(first_arg, sp); // (first argument - see note below) = Handle<Name>
__ Addu(second_arg, sp, kPointerSize);
const int kStackUnwindSpace = kFastApiCallArguments + 1;
+
ApiFunction fun(getter_address);
ExternalReference::Type type =
returns_handle ?
ExternalReference::DIRECT_GETTER_CALL :
ExternalReference::DIRECT_GETTER_CALL_NEW;
-
ExternalReference ref = ExternalReference(&fun, type, isolate());
+
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeAccessorGetter)
+ : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ ExternalReference::Type thunk_type =
+ returns_handle ?
+ ExternalReference::PROFILING_GETTER_CALL :
+ ExternalReference::PROFILING_GETTER_CALL_NEW;
+ ApiFunction thunk_fun(thunk_address);
+ ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+ isolate());
__ CallApiFunctionAndReturn(ref,
+ getter_address,
+ thunk_ref,
+ third_arg,
kStackUnwindSpace,
returns_handle,
5);
void SampleContext(Sampler* sampler) {
if (!SignalHandler::Installed()) return;
pthread_t tid = sampler->platform_data()->vm_tid();
- int result = pthread_kill(tid, SIGPROF);
- USE(result);
- ASSERT(result == 0);
+ pthread_kill(tid, SIGPROF);
}
#elif defined(__MACH__)
void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
+ Address thunk_address,
+ Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset) {
PopSafepointRegisters();
}
+
+ Label profiler_disabled;
+ Label end_profiler_check;
+ bool* is_profiling_flag =
+ isolate()->cpu_profiler()->is_profiling_address();
+ STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
+ movq(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE);
+ cmpb(Operand(rax, 0), Immediate(0));
+ j(zero, &profiler_disabled);
+
+ // Third parameter is the address of the actual getter function.
+ movq(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE);
+ movq(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE);
+ jmp(&end_profiler_check);
+
+ bind(&profiler_disabled);
// Call the api function!
movq(rax, reinterpret_cast<int64_t>(function_address),
RelocInfo::EXTERNAL_REFERENCE);
+
+ bind(&end_profiler_check);
+
+ // Call the api function!
call(rax);
if (FLAG_log_timer_events) {
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
void CallApiFunctionAndReturn(Address function_address,
+ Address thunk_address,
+ Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_rbp);
#if defined(__MINGW64__)
Register arguments_arg = rcx;
+ Register callback_arg = rdx;
#elif defined(_WIN64)
// Win64 uses first register--rcx--for returned value.
Register arguments_arg = returns_handle ? rdx : rcx;
+ Register callback_arg = returns_handle ? r8 : rdx;
#else
Register arguments_arg = rdi;
+ Register callback_arg = rsi;
#endif
// Allocate the v8::Arguments structure in the arguments' space since
// v8::InvocationCallback's argument.
__ lea(arguments_arg, StackSpaceOperand(0));
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeInvocationCallback)
+ : FUNCTION_ADDR(&InvokeFunctionCallback);
+
__ CallApiFunctionAndReturn(function_address,
+ thunk_address,
+ callback_arg,
argc + kFastApiCallArguments + 1,
returns_handle,
kFastApiCallArguments + 1);
!CallbackTable::ReturnsVoid(isolate(), getter_address);
#if defined(__MINGW64__)
+ Register getter_arg = r8;
Register accessor_info_arg = rdx;
Register name_arg = rcx;
#elif defined(_WIN64)
// Win64 uses first register--rcx--for returned value.
+ Register getter_arg = returns_handle ? r9 : r8;
Register accessor_info_arg = returns_handle ? r8 : rdx;
Register name_arg = returns_handle ? rdx : rcx;
#else
+ Register getter_arg = rdx;
Register accessor_info_arg = rsi;
Register name_arg = rdi;
#endif
// could be used to pass arguments.
__ lea(accessor_info_arg, StackSpaceOperand(0));
+ Address thunk_address = returns_handle
+ ? FUNCTION_ADDR(&InvokeAccessorGetter)
+ : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+
__ CallApiFunctionAndReturn(getter_address,
+ thunk_address,
+ getter_arg,
kStackSpace,
returns_handle,
5);
template<typename T>
-static void CheckReturnValue(const T& t) {
+static void CheckReturnValue(const T& t, i::Address callback) {
v8::ReturnValue<v8::Value> rv = t.GetReturnValue();
i::Object** o = *reinterpret_cast<i::Object***>(&rv);
CHECK_EQ(v8::Isolate::GetCurrent(), t.GetIsolate());
rv.Set(v8::Handle<v8::Object>());
CHECK((*o)->IsTheHole() || (*o)->IsUndefined());
CHECK_EQ(is_runtime, (*o)->IsTheHole());
+
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(t.GetIsolate());
+ // If CPU profiler is active check that when API callback is invoked
+ // VMState is set to EXTERNAL.
+ if (isolate->cpu_profiler()->is_profiling()) {
+ CHECK_EQ(i::EXTERNAL, isolate->current_vm_state());
+ CHECK(isolate->external_callback());
+ CHECK_EQ(callback, isolate->external_callback());
+ }
}
-static v8::Handle<Value> handle_call(const v8::Arguments& args) {
+static v8::Handle<Value> handle_call_impl(
+ const v8::Arguments& args,
+ i::Address callback) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, callback);
args.GetReturnValue().Set(v8_str("bad value"));
return v8_num(102);
}
+static v8::Handle<Value> handle_call(const v8::Arguments& args) {
+ return handle_call_impl(args, FUNCTION_ADDR(handle_call));
+}
+
static v8::Handle<Value> handle_call_2(const v8::Arguments& args) {
- return handle_call(args);
+ return handle_call_impl(args, FUNCTION_ADDR(handle_call_2));
}
-static v8::Handle<Value> handle_call_indirect(const v8::Arguments& args) {
+static v8::Handle<Value> handle_call_indirect_impl(const v8::Arguments& args,
+ i::Address callback) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, callback);
args.GetReturnValue().Set(v8_str("bad value"));
args.GetReturnValue().Set(v8_num(102));
return v8::Handle<Value>();
}
+static v8::Handle<Value> handle_call_indirect(const v8::Arguments& args) {
+ return handle_call_indirect_impl(args, FUNCTION_ADDR(handle_call_indirect));
+}
+
static v8::Handle<Value> handle_call_indirect_2(const v8::Arguments& args) {
- return handle_call_indirect(args);
+ return handle_call_indirect_impl(args, FUNCTION_ADDR(handle_call_indirect_2));
}
-static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) {
+static void handle_callback_impl(const v8::FunctionCallbackInfo<Value>& info,
+ i::Address callback) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, callback);
info.GetReturnValue().Set(v8_str("bad value"));
info.GetReturnValue().Set(v8_num(102));
}
+static void handle_callback(const v8::FunctionCallbackInfo<Value>& info) {
+ return handle_callback_impl(info, FUNCTION_ADDR(handle_callback));
+}
+
static void handle_callback_2(const v8::FunctionCallbackInfo<Value>& info) {
- return handle_callback(info);
+ return handle_callback_impl(info, FUNCTION_ADDR(handle_callback_2));
}
static v8::Handle<Value> construct_call(const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, FUNCTION_ADDR(construct_call));
args.This()->Set(v8_str("x"), v8_num(1));
args.This()->Set(v8_str("y"), v8_num(2));
args.GetReturnValue().Set(v8_str("bad value"));
static v8::Handle<Value> construct_call_indirect(const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, FUNCTION_ADDR(construct_call_indirect));
args.This()->Set(v8_str("x"), v8_num(1));
args.This()->Set(v8_str("y"), v8_num(2));
args.GetReturnValue().Set(v8_str("bad value"));
static void construct_callback(
const v8::FunctionCallbackInfo<Value>& info) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(construct_callback));
info.This()->Set(v8_str("x"), v8_num(1));
info.This()->Set(v8_str("y"), v8_num(2));
info.GetReturnValue().Set(v8_str("bad value"));
static v8::Handle<Value> Return239(
Local<String> name, const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(Return239));
info.GetReturnValue().Set(v8_str("bad value"));
return v8_num(239);
}
static v8::Handle<Value> Return239Indirect(
Local<String> name, const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(Return239Indirect));
Handle<Value> value = v8_num(239);
info.GetReturnValue().Set(v8_str("bad value"));
info.GetReturnValue().Set(value);
static void Return239Callback(
Local<String> name, const v8::PropertyCallbackInfo<Value>& info) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(Return239Callback));
info.GetReturnValue().Set(v8_str("bad value"));
info.GetReturnValue().Set(v8_num(239));
}
template<typename Handler>
static void TestFunctionTemplateInitializer(Handler handler,
Handler handler_2) {
- // Test constructor calls.
- {
+ for (int i = 0; i < 2; i++) {
+ bool is_profiling = (i > 0);
+ // Test constructor calls.
+ {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ v8::Local<v8::String> profile_name = v8::String::New("my_profile1");
+ v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+ if (is_profiling) {
+ cpu_profiler->StartCpuProfiling(profile_name);
+ }
+
+ Local<v8::FunctionTemplate> fun_templ =
+ v8::FunctionTemplate::New(handler);
+ Local<Function> fun = fun_templ->GetFunction();
+ env->Global()->Set(v8_str("obj"), fun);
+ Local<Script> script = v8_compile("obj()");
+ for (int i = 0; i < 30; i++) {
+ CHECK_EQ(102, script->Run()->Int32Value());
+ }
+
+ if (is_profiling) {
+ cpu_profiler->StopCpuProfiling(profile_name);
+ }
+ }
+ // Use SetCallHandler to initialize a function template, should work like
+ // the previous one.
+ {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ v8::Local<v8::String> profile_name = v8::String::New("my_profile2");
+ v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+ if (is_profiling) {
+ cpu_profiler->StartCpuProfiling(profile_name);
+ }
+
+ Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ fun_templ->SetCallHandler(handler_2);
+ Local<Function> fun = fun_templ->GetFunction();
+ env->Global()->Set(v8_str("obj"), fun);
+ Local<Script> script = v8_compile("obj()");
+ for (int i = 0; i < 30; i++) {
+ CHECK_EQ(102, script->Run()->Int32Value());
+ }
+
+ if (is_profiling) {
+ cpu_profiler->DeleteAllCpuProfiles();
+ }
+ }
+ }
+}
+
+
+template<typename Constructor, typename Accessor>
+static void TestFunctionTemplateAccessor(Constructor constructor,
+ Accessor accessor) {
+ for (int i = 0; i < 2; i++) {
+ bool is_profiling = (i > 0);
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
+
+ v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+ if (is_profiling) {
+ v8::Local<v8::String> profile_name = v8::String::New("my_profile1");
+ cpu_profiler->StartCpuProfiling(profile_name);
+ }
+
Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(handler);
+ v8::FunctionTemplate::New(constructor);
+ fun_templ->SetClassName(v8_str("funky"));
+ fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), accessor);
Local<Function> fun = fun_templ->GetFunction();
env->Global()->Set(v8_str("obj"), fun);
- Local<Script> script = v8_compile("obj()");
+ Local<Value> result = v8_compile("(new obj()).toString()")->Run();
+ CHECK_EQ(v8_str("[object funky]"), result);
+ CompileRun("var obj_instance = new obj();");
+ Local<Script> script;
+ script = v8_compile("obj_instance.x");
for (int i = 0; i < 30; i++) {
- CHECK_EQ(102, script->Run()->Int32Value());
+ CHECK_EQ(1, script->Run()->Int32Value());
}
- }
- // Use SetCallHandler to initialize a function template, should work like the
- // previous one.
- {
- LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
- fun_templ->SetCallHandler(handler_2);
- Local<Function> fun = fun_templ->GetFunction();
- env->Global()->Set(v8_str("obj"), fun);
- Local<Script> script = v8_compile("obj()");
+ script = v8_compile("obj_instance.m");
for (int i = 0; i < 30; i++) {
- CHECK_EQ(102, script->Run()->Int32Value());
+ CHECK_EQ(239, script->Run()->Int32Value());
}
- }
-}
-
-template<typename Constructor, typename Accessor>
-static void TestFunctionTemplateAccessor(Constructor constructor,
- Accessor accessor) {
- LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- Local<v8::FunctionTemplate> fun_templ =
- v8::FunctionTemplate::New(constructor);
- fun_templ->SetClassName(v8_str("funky"));
- fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), accessor);
- Local<Function> fun = fun_templ->GetFunction();
- env->Global()->Set(v8_str("obj"), fun);
- Local<Value> result = v8_compile("(new obj()).toString()")->Run();
- CHECK_EQ(v8_str("[object funky]"), result);
- CompileRun("var obj_instance = new obj();");
- Local<Script> script;
- script = v8_compile("obj_instance.x");
- for (int i = 0; i < 30; i++) {
- CHECK_EQ(1, script->Run()->Int32Value());
- }
- script = v8_compile("obj_instance.m");
- for (int i = 0; i < 30; i++) {
- CHECK_EQ(239, script->Run()->Int32Value());
+ if (is_profiling) {
+ cpu_profiler->DeleteAllCpuProfiles();
+ }
}
}
static v8::Handle<v8::Value> SimpleDirectCallback(const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, FUNCTION_ADDR(SimpleDirectCallback));
args.GetReturnValue().Set(v8_str("bad value"));
return v8_num(51423 + args.Length());
}
static v8::Handle<v8::Value> SimpleIndirectCallback(const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, FUNCTION_ADDR(SimpleIndirectCallback));
args.GetReturnValue().Set(v8_num(51423 + args.Length()));
return v8::Handle<v8::Value>();
}
static void SimpleCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(SimpleCallback));
info.GetReturnValue().Set(v8_num(51423 + info.Length()));
}
template<typename Callback>
static void TestSimpleCallback(Callback callback) {
- LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
- object_template->Set("callback", v8::FunctionTemplate::New(callback));
- v8::Local<v8::Object> object = object_template->NewInstance();
- (*env)->Global()->Set(v8_str("callback_object"), object);
- v8::Handle<v8::Script> script;
- script = v8_compile("callback_object.callback(17)");
- for (int i = 0; i < 30; i++) {
- CHECK_EQ(51424, script->Run()->Int32Value());
- }
- script = v8_compile("callback_object.callback(17, 24)");
- for (int i = 0; i < 30; i++) {
- CHECK_EQ(51425, script->Run()->Int32Value());
+ for (int i = 0; i < 2; i++) {
+ bool is_profiling = i;
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+ if (is_profiling) {
+ v8::Local<v8::String> profile_name = v8::String::New("my_profile1");
+ cpu_profiler->StartCpuProfiling(profile_name);
+ }
+
+ v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New();
+ object_template->Set("callback", v8::FunctionTemplate::New(callback));
+ v8::Local<v8::Object> object = object_template->NewInstance();
+ (*env)->Global()->Set(v8_str("callback_object"), object);
+ v8::Handle<v8::Script> script;
+ script = v8_compile("callback_object.callback(17)");
+ for (int i = 0; i < 30; i++) {
+ CHECK_EQ(51424, script->Run()->Int32Value());
+ }
+ script = v8_compile("callback_object.callback(17, 24)");
+ for (int i = 0; i < 30; i++) {
+ CHECK_EQ(51425, script->Run()->Int32Value());
+ }
+
+ if (is_profiling) {
+ cpu_profiler->DeleteAllCpuProfiles();
+ }
}
}
template<>
void FastReturnValueCallback<int32_t>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(FastReturnValueCallback<int32_t>));
info.GetReturnValue().Set(fast_return_value_int32);
}
template<>
void FastReturnValueCallback<uint32_t>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(FastReturnValueCallback<uint32_t>));
info.GetReturnValue().Set(fast_return_value_uint32);
}
template<>
void FastReturnValueCallback<double>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(FastReturnValueCallback<double>));
info.GetReturnValue().Set(kFastReturnValueDouble);
}
template<>
void FastReturnValueCallback<bool>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(FastReturnValueCallback<bool>));
info.GetReturnValue().Set(fast_return_value_bool);
}
template<>
void FastReturnValueCallback<void>(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(FastReturnValueCallback<void>));
switch (fast_return_value_void) {
case kNullReturnValue:
info.GetReturnValue().SetNull();
static void CheckThisIndexedPropertyHandler(
uint32_t index,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyHandler));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
static void CheckThisNamedPropertyHandler(
Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
uint32_t index,
Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
Local<String> property,
Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
void CheckThisIndexedPropertyQuery(
uint32_t index,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyQuery));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
void CheckThisNamedPropertyQuery(
Local<String> property,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyQuery));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
void CheckThisIndexedPropertyDeleter(
uint32_t index,
const v8::PropertyCallbackInfo<v8::Boolean>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDeleter));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
void CheckThisNamedPropertyDeleter(
Local<String> property,
const v8::PropertyCallbackInfo<v8::Boolean>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDeleter));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
void CheckThisIndexedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyEnumerator));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
void CheckThisNamedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyEnumerator));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
}
static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(InterceptorCallICFastApi));
int* call_count =
reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value());
++(*call_count);
static v8::Handle<Value> FastApiCallback_TrivialSignature(
const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, FUNCTION_ADDR(FastApiCallback_TrivialSignature));
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, args.GetIsolate());
CHECK_EQ(args.This(), args.Holder());
static v8::Handle<Value> FastApiCallback_SimpleSignature(
const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
- CheckReturnValue(args);
+ CheckReturnValue(args, FUNCTION_ADDR(FastApiCallback_SimpleSignature));
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, args.GetIsolate());
CHECK_EQ(args.This()->GetPrototype(), args.Holder());
static v8::Handle<v8::Value> DirectGetter(Local<String> name,
const v8::AccessorInfo& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(DirectGetter));
info.GetReturnValue().Set(v8_str("Garbage"));
return DoDirectGetter();
}
static v8::Handle<v8::Value> DirectGetterIndirect(
Local<String> name,
const v8::AccessorInfo& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(DirectGetterIndirect));
info.GetReturnValue().Set(DoDirectGetter());
return v8::Handle<v8::Value>();
}
static void DirectGetterCallback(
Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- CheckReturnValue(info);
+ CheckReturnValue(info, FUNCTION_ADDR(DirectGetterCallback));
info.GetReturnValue().Set(DoDirectGetter());
}
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
const v8::CpuProfileNode* startNode = GetChild(root, "start");
- // TODO(yurys): in LoadIC should be changed to report external callback
- // invocation. See r13768 where it was LoadCallbackProperty was removed.
- // GetChild(startNode, "get foo");
+ GetChild(startNode, "get foo");
GetChild(startNode, "set foo");
cpu_profiler->DeleteAllCpuProfiles();
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
GetChild(root, "start");
- // TODO(yurys): in CallIC should be changed to report external callback
- // invocation.
- // GetChild(startNode, "fooMethod");
+ const v8::CpuProfileNode* startNode = GetChild(root, "start");
+ GetChild(startNode, "fooMethod");
cpu_profiler->DeleteAllCpuProfiles();
}