From 2f732c27280b22aefb45cd0aeac18dfa738a716e Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Fri, 13 Apr 2012 09:38:00 +0000 Subject: [PATCH] Add isolate accessor to AccessorInfo and Arguments. This passes the isolate through to API callback functions so that it is available through AccessorInfo and Arguments. This allows bindings to avoid unnecessary TLS lookups to retrieve the current isolate. R=danno@chromium.org TEST=cctest/test-api,cctest/test-accessors Review URL: https://chromiumcodereview.appspot.com/10069050 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11306 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 22 ++++++++++++--- src/apiutils.h | 9 ++++-- src/arguments.h | 12 ++++---- src/arm/stub-cache-arm.cc | 52 +++++++++++++++++++--------------- src/builtins.cc | 66 ++----------------------------------------- src/builtins.h | 1 - src/ia32/stub-cache-ia32.cc | 30 ++++++++++++-------- src/stub-cache.cc | 10 ++++--- src/x64/stub-cache-x64.cc | 32 ++++++++++++--------- test/cctest/test-accessors.cc | 9 +++++- test/cctest/test-api.cc | 6 ++++ 11 files changed, 120 insertions(+), 129 deletions(-) diff --git a/include/v8.h b/include/v8.h index 7d7a866..a55e134 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -107,6 +107,7 @@ class Data; class AccessorInfo; class StackTrace; class StackFrame; +class Isolate; namespace internal { @@ -1967,10 +1968,12 @@ class Arguments { inline Local Holder() const; inline bool IsConstructCall() const; inline Local Data() const; + inline Isolate* GetIsolate() const; private: - static const int kDataIndex = 0; - static const int kCalleeIndex = -1; - static const int kHolderIndex = -2; + static const int kIsolateIndex = 0; + static const int kDataIndex = -1; + static const int kCalleeIndex = -2; + static const int kHolderIndex = -3; friend class ImplementationUtilities; inline Arguments(internal::Object** implicit_args, @@ -1992,6 +1995,7 @@ class V8EXPORT AccessorInfo { public: inline AccessorInfo(internal::Object** args) : args_(args) { } + inline Isolate* GetIsolate() const; inline Local Data() const; inline Local This() const; inline Local Holder() const; @@ -4055,6 +4059,11 @@ Local Arguments::Data() const { } +Isolate* Arguments::GetIsolate() const { + return *reinterpret_cast(&implicit_args_[kIsolateIndex]); +} + + bool Arguments::IsConstructCall() const { return is_construct_call_; } @@ -4290,6 +4299,11 @@ External* External::Cast(v8::Value* value) { } +Isolate* AccessorInfo::GetIsolate() const { + return *reinterpret_cast(&args_[-3]); +} + + Local AccessorInfo::Data() const { return Local(reinterpret_cast(&args_[-2])); } diff --git a/src/apiutils.h b/src/apiutils.h index 68579af..71c0e1c 100644 --- a/src/apiutils.h +++ b/src/apiutils.h @@ -1,4 +1,4 @@ -// Copyright 2009 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -40,14 +40,17 @@ class ImplementationUtilities { } // Packs additional parameters for the NewArguments function. |implicit_args| - // is a pointer to the last element of 3-elements array controlled by GC. + // is a pointer to the last element of 4-elements array controlled by GC. static void PrepareArgumentsData(internal::Object** implicit_args, + internal::Isolate* isolate, internal::Object* data, internal::JSFunction* callee, internal::Object* holder) { implicit_args[v8::Arguments::kDataIndex] = data; implicit_args[v8::Arguments::kCalleeIndex] = callee; implicit_args[v8::Arguments::kHolderIndex] = holder; + implicit_args[v8::Arguments::kIsolateIndex] = + reinterpret_cast(isolate); } static v8::Arguments NewArguments(internal::Object** implicit_args, @@ -55,6 +58,8 @@ class ImplementationUtilities { bool is_construct_call) { ASSERT(implicit_args[v8::Arguments::kCalleeIndex]->IsJSFunction()); ASSERT(implicit_args[v8::Arguments::kHolderIndex]->IsHeapObject()); + // The implicit isolate argument is not tagged and looks like a SMI. + ASSERT(implicit_args[v8::Arguments::kIsolateIndex]->IsSmi()); return v8::Arguments(implicit_args, argv, argc, is_construct_call); } diff --git a/src/arguments.h b/src/arguments.h index e9a3270..2b8dddb 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -91,9 +91,11 @@ class CustomArguments : public Relocatable { Object* data, Object* self, JSObject* holder) : Relocatable(isolate) { - values_[2] = self; - values_[1] = holder; - values_[0] = data; + ASSERT(reinterpret_cast(isolate)->IsSmi()); + values_[3] = self; + values_[2] = holder; + values_[1] = data; + values_[0] = reinterpret_cast(isolate); } inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) { @@ -107,7 +109,7 @@ class CustomArguments : public Relocatable { void IterateInstance(ObjectVisitor* v); Object** end() { return values_ + ARRAY_SIZE(values_) - 1; } private: - Object* values_[3]; + Object* values_[4]; }; diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 4b1a054..1cd0e65 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -582,6 +582,8 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ push(holder); __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); __ push(scratch); + __ mov(scratch, Operand(ExternalReference::isolate_address())); + __ push(scratch); } @@ -596,7 +598,7 @@ static void CompileCallLoadPropertyWithInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()); - __ mov(r0, Operand(5)); + __ mov(r0, Operand(6)); __ mov(r1, Operand(ref)); CEntryStub stub(1); @@ -604,9 +606,9 @@ static void CompileCallLoadPropertyWithInterceptor( } -static const int kFastApiCallArguments = 3; +static const int kFastApiCallArguments = 4; -// Reserves space for the extra arguments to FastHandleApiCall in the +// Reserves space for the extra arguments to API function in the // caller's frame. // // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. @@ -632,7 +634,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // -- sp[0] : holder (set by CheckPrototypes) // -- sp[4] : callee JS function // -- sp[8] : call data - // -- sp[12] : last JS argument + // -- sp[12] : isolate + // -- sp[16] : last JS argument // -- ... // -- sp[(argc + 3) * 4] : first JS argument // -- sp[(argc + 4) * 4] : receiver @@ -642,7 +645,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, __ LoadHeapObject(r5, function); __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset)); - // Pass the additional arguments FastHandleApiCall expects. + // Pass the additional arguments. Handle api_call_info = optimization.api_call_info(); Handle call_data(api_call_info->data()); if (masm->isolate()->heap()->InNewSpace(*call_data)) { @@ -651,13 +654,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, } else { __ Move(r6, call_data); } - // Store JS function and call data. - __ stm(ib, sp, r5.bit() | r6.bit()); + __ mov(r7, Operand(ExternalReference::isolate_address())); + // Store JS function, call data and isolate. + __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit()); - // r2 points to call data as expected by Arguments - // (refer to layout above). - __ add(r2, sp, Operand(2 * kPointerSize)); + // Prepare arguments. + __ add(r2, sp, Operand(3 * kPointerSize)); + // Allocate the v8::Arguments structure in the arguments' space since + // it's not controlled by GC. const int kApiStackSpace = 4; FrameScope frame_scope(masm, StackFrame::MANUAL); @@ -666,9 +671,9 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // r0 = v8::Arguments& // Arguments is after the return address. __ add(r0, sp, Operand(1 * kPointerSize)); - // v8::Arguments::implicit_args = data + // v8::Arguments::implicit_args_ __ str(r2, MemOperand(r0, 0 * kPointerSize)); - // v8::Arguments::values = last argument + // v8::Arguments::values_ __ add(ip, r2, Operand(argc * kPointerSize)); __ str(ip, MemOperand(r0, 1 * kPointerSize)); // v8::Arguments::length_ = argc @@ -845,7 +850,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 5); + 6); // Restore the name_ register. __ pop(name_); // Leave the internal frame. @@ -1204,7 +1209,9 @@ void StubCompiler::GenerateLoadCallback(Handle object, } else { __ Move(scratch3, Handle(callback->data())); } - __ Push(reg, scratch3, name_reg); + __ Push(reg, scratch3); + __ mov(scratch3, Operand(ExternalReference::isolate_address())); + __ Push(scratch3, name_reg); __ mov(r0, sp); // r0 = Handle const int kApiStackSpace = 1; @@ -1216,7 +1223,7 @@ void StubCompiler::GenerateLoadCallback(Handle object, __ str(scratch2, MemOperand(sp, 1 * kPointerSize)); __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& - const int kStackUnwindSpace = 4; + const int kStackUnwindSpace = 5; Address getter_address = v8::ToCData
(callback->getter()); ApiFunction fun(getter_address); ExternalReference ref = @@ -1337,20 +1344,19 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, if (!receiver.is(holder_reg)) { ASSERT(scratch1.is(holder_reg)); __ Push(receiver, holder_reg); - __ ldr(scratch3, - FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); - __ Push(scratch3, scratch2, name_reg); } else { __ push(receiver); - __ ldr(scratch3, - FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); - __ Push(holder_reg, scratch3, scratch2, name_reg); + __ push(holder_reg); } + __ ldr(scratch3, + FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); + __ mov(scratch1, Operand(ExternalReference::isolate_address())); + __ Push(scratch3, scratch1, scratch2, name_reg); ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), masm()->isolate()); - __ TailCallExternalReference(ref, 5, 1); + __ TailCallExternalReference(ref, 6, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1364,7 +1370,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); - __ TailCallExternalReference(ref, 5, 1); + __ TailCallExternalReference(ref, 6, 1); } } diff --git a/src/builtins.cc b/src/builtins.cc index 0f493e6..0f79510 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -1098,7 +1098,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper( CustomArguments custom(isolate); v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), - data_obj, *function, raw_holder); + isolate, data_obj, *function, raw_holder); v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( custom.end(), @@ -1138,68 +1138,6 @@ BUILTIN(HandleApiCallConstruct) { } -#ifdef DEBUG - -static void VerifyTypeCheck(Handle object, - Handle function) { - ASSERT(function->shared()->IsApiFunction()); - FunctionTemplateInfo* info = function->shared()->get_api_func_data(); - if (info->signature()->IsUndefined()) return; - SignatureInfo* signature = SignatureInfo::cast(info->signature()); - Object* receiver_type = signature->receiver(); - if (receiver_type->IsUndefined()) return; - FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type); - ASSERT(object->IsInstanceOf(type)); -} - -#endif - - -BUILTIN(FastHandleApiCall) { - ASSERT(!CalledAsConstructor(isolate)); - Heap* heap = isolate->heap(); - const bool is_construct = false; - - // We expect four more arguments: callback, function, call data, and holder. - const int args_length = args.length() - 4; - ASSERT(args_length >= 0); - - Object* callback_obj = args[args_length]; - - v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( - &args[args_length + 1], - &args[0] - 1, - args_length - 1, - is_construct); - -#ifdef DEBUG - VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()), - Utils::OpenHandle(*new_args.Callee())); -#endif - HandleScope scope(isolate); - Object* result; - v8::Handle value; - { - // Leaving JavaScript. - VMState state(isolate, EXTERNAL); - ExternalCallbackScope call_scope(isolate, - v8::ToCData
(callback_obj)); - v8::InvocationCallback callback = - v8::ToCData(callback_obj); - - value = callback(new_args); - } - if (value.IsEmpty()) { - result = heap->undefined_value(); - } else { - result = *reinterpret_cast(*value); - } - - RETURN_IF_SCHEDULED_EXCEPTION(isolate); - return result; -} - - // Helper function to handle calls to non-function objects created through the // API. The object can be called as either a constructor (using new) or just as // a function (without new). @@ -1238,7 +1176,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor( CustomArguments custom(isolate); v8::ImplementationUtilities::PrepareArgumentsData(custom.end(), - call_data->data(), constructor, obj); + isolate, call_data->data(), constructor, obj); v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( custom.end(), &args[0] - 1, diff --git a/src/builtins.h b/src/builtins.h index f079139..3ea3393 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -56,7 +56,6 @@ enum BuiltinExtraArguments { V(ArrayConcat, NO_EXTRA_ARGUMENTS) \ \ V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ - V(FastHandleApiCall, NO_EXTRA_ARGUMENTS) \ V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \ diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index f2867de..d783415 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -406,6 +406,7 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ push(receiver); __ push(holder); __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); + __ push(Immediate(reinterpret_cast(masm->isolate()))); } @@ -419,12 +420,12 @@ static void CompileCallLoadPropertyWithInterceptor( __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()), - 5); + 6); } // Number of pointers to be reserved on stack for fast API call. -static const int kFastApiCallArguments = 3; +static const int kFastApiCallArguments = 4; // Reserves space for the extra arguments to API function in the @@ -472,10 +473,11 @@ static void GenerateFastApiCall(MacroAssembler* masm, // -- esp[8] : api function // (first fast api call extra argument) // -- esp[12] : api call data - // -- esp[16] : last argument + // -- esp[16] : isolate + // -- esp[20] : last argument // -- ... - // -- esp[(argc + 3) * 4] : first argument - // -- esp[(argc + 4) * 4] : receiver + // -- esp[(argc + 4) * 4] : first argument + // -- esp[(argc + 5) * 4] : receiver // ----------------------------------- // Get the function and setup the context. Handle function = optimization.constant_function(); @@ -493,9 +495,11 @@ static void GenerateFastApiCall(MacroAssembler* masm, } else { __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data)); } + __ mov(Operand(esp, 4 * kPointerSize), + Immediate(reinterpret_cast(masm->isolate()))); // Prepare arguments. - __ lea(eax, Operand(esp, 3 * kPointerSize)); + __ lea(eax, Operand(esp, 4 * kPointerSize)); const int kApiArgc = 1; // API function gets reference to the v8::Arguments. @@ -679,7 +683,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 5); + 6); // Restore the name_ register. __ pop(name_); @@ -1034,6 +1038,7 @@ void StubCompiler::GenerateLoadCallback(Handle object, } else { __ push(Immediate(Handle(callback->data()))); } + __ push(Immediate(reinterpret_cast(isolate()))); // Save a pointer to where we pushed the arguments pointer. // This will be passed as the const AccessorInfo& to the C++ callback. @@ -1044,9 +1049,9 @@ void StubCompiler::GenerateLoadCallback(Handle object, __ push(scratch3); // Restore return address. - // 3 elements array for v8::Arguments::values_, handler for name and pointer + // 4 elements array for v8::Arguments::values_, handler for name and pointer // to the values (it considered as smi in GC). - const int kStackSpace = 5; + const int kStackSpace = 6; const int kApiArgc = 2; __ PrepareCallApiFunction(kApiArgc); @@ -1199,6 +1204,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, __ push(holder_reg); __ mov(holder_reg, Immediate(callback)); __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); + __ push(Immediate(reinterpret_cast(isolate()))); __ push(holder_reg); __ push(name_reg); __ push(scratch2); // restore return address @@ -1206,7 +1212,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), masm()->isolate()); - __ TailCallExternalReference(ref, 5, 1); + __ TailCallExternalReference(ref, 6, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1222,7 +1228,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); - __ TailCallExternalReference(ref, 5, 1); + __ TailCallExternalReference(ref, 6, 1); } } @@ -2160,7 +2166,7 @@ Handle CallStubCompiler::CompileFastApiCall( name, depth, &miss); // Move the return address on top of the stack. - __ mov(eax, Operand(esp, 3 * kPointerSize)); + __ mov(eax, Operand(esp, 4 * kPointerSize)); __ mov(Operand(esp, 0 * kPointerSize), eax); // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 3371b1b..bd7163a 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -939,7 +939,8 @@ void StubCache::CollectMatchingMaps(SmallMapList* types, RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) { ASSERT(args[0]->IsJSObject()); ASSERT(args[1]->IsJSObject()); - AccessorInfo* callback = AccessorInfo::cast(args[3]); + ASSERT(args[3]->IsSmi()); + AccessorInfo* callback = AccessorInfo::cast(args[4]); Address getter_address = v8::ToCData
(callback->getter()); v8::AccessorGetter fun = FUNCTION_CAST(getter_address); ASSERT(fun != NULL); @@ -950,7 +951,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) { // Leaving JavaScript. VMState state(isolate, EXTERNAL); ExternalCallbackScope call_scope(isolate, getter_address); - result = fun(v8::Utils::ToLocal(args.at(4)), info); + result = fun(v8::Utils::ToLocal(args.at(5)), info); } RETURN_IF_SCHEDULED_EXCEPTION(isolate); if (result.IsEmpty()) return HEAP->undefined_value(); @@ -997,7 +998,8 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) { ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); ASSERT(args[2]->IsJSObject()); // Receiver. ASSERT(args[3]->IsJSObject()); // Holder. - ASSERT(args.length() == 5); // Last arg is data object. + ASSERT(args[5]->IsSmi()); // Isolate. + ASSERT(args.length() == 6); Address getter_address = v8::ToCData
(interceptor_info->getter()); v8::NamedPropertyGetter getter = @@ -1050,7 +1052,7 @@ static MaybeObject* LoadWithInterceptor(Arguments* args, ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); Handle receiver_handle = args->at(2); Handle holder_handle = args->at(3); - ASSERT(args->length() == 5); // Last arg is data object. + ASSERT(args->length() == 6); Isolate* isolate = receiver_handle->GetIsolate(); diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index af810c1..fed2f26 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -379,6 +379,7 @@ static void PushInterceptorArguments(MacroAssembler* masm, __ push(receiver); __ push(holder); __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); + __ push(Immediate(reinterpret_cast(masm->isolate()))); } @@ -393,7 +394,7 @@ static void CompileCallLoadPropertyWithInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), masm->isolate()); - __ Set(rax, 5); + __ Set(rax, 6); __ LoadAddress(rbx, ref); CEntryStub stub(1); @@ -402,7 +403,7 @@ static void CompileCallLoadPropertyWithInterceptor( // Number of pointers to be reserved on stack for fast API call. -static const int kFastApiCallArguments = 3; +static const int kFastApiCallArguments = 4; // Reserves space for the extra arguments to API function in the @@ -452,10 +453,11 @@ static void GenerateFastApiCall(MacroAssembler* masm, // -- rsp[16] : api function // (first fast api call extra argument) // -- rsp[24] : api call data - // -- rsp[32] : last argument + // -- rsp[32] : isolate + // -- rsp[40] : last argument // -- ... - // -- rsp[(argc + 3) * 8] : first argument - // -- rsp[(argc + 4) * 8] : receiver + // -- rsp[(argc + 4) * 8] : first argument + // -- rsp[(argc + 5) * 8] : receiver // ----------------------------------- // Get the function and setup the context. Handle function = optimization.constant_function(); @@ -473,9 +475,11 @@ static void GenerateFastApiCall(MacroAssembler* masm, } else { __ Move(Operand(rsp, 3 * kPointerSize), call_data); } + __ movq(Operand(rsp, 4 * kPointerSize), + Immediate(reinterpret_cast(masm->isolate()))); // Prepare arguments. - __ lea(rbx, Operand(rsp, 3 * kPointerSize)); + __ lea(rbx, Operand(rsp, 4 * kPointerSize)); #ifdef _WIN64 // Win64 uses first register--rcx--for returned value. @@ -663,7 +667,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { __ CallExternalReference( ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), - 5); + 6); // Restore the name_ register. __ pop(name_); @@ -1005,6 +1009,7 @@ void StubCompiler::GenerateLoadCallback(Handle object, } else { __ Push(Handle(callback->data())); } + __ push(Immediate(reinterpret_cast(isolate()))); // isolate __ push(name_reg); // name // Save a pointer to where we pushed the arguments pointer. // This will be passed as the const AccessorInfo& to the C++ callback. @@ -1022,14 +1027,14 @@ void StubCompiler::GenerateLoadCallback(Handle object, __ movq(name_arg, rsp); __ push(scratch2); // Restore return address. - // 3 elements array for v8::Arguments::values_ and handler for name. - const int kStackSpace = 4; + // 4 elements array for v8::Arguments::values_ and handler for name. + const int kStackSpace = 5; // Allocate v8::AccessorInfo in non-GCed stack space. const int kArgStackSpace = 1; __ PrepareCallApiFunction(kArgStackSpace); - __ lea(rax, Operand(name_arg, 3 * kPointerSize)); + __ lea(rax, Operand(name_arg, 4 * kPointerSize)); // v8::AccessorInfo::args_. __ movq(StackSpaceOperand(0), rax); @@ -1179,6 +1184,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, __ push(holder_reg); __ Move(holder_reg, callback); __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); + __ push(Immediate(reinterpret_cast(isolate()))); __ push(holder_reg); __ push(name_reg); __ push(scratch2); // restore return address @@ -1186,7 +1192,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadCallbackProperty), isolate()); - __ TailCallExternalReference(ref, 5, 1); + __ TailCallExternalReference(ref, 6, 1); } } else { // !compile_followup_inline // Call the runtime system to load the interceptor. @@ -1201,7 +1207,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle object, ExternalReference ref = ExternalReference( IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); - __ TailCallExternalReference(ref, 5, 1); + __ TailCallExternalReference(ref, 6, 1); } } @@ -1993,7 +1999,7 @@ Handle CallStubCompiler::CompileFastApiCall( name, depth, &miss); // Move the return address on top of the stack. - __ movq(rax, Operand(rsp, 3 * kPointerSize)); + __ movq(rax, Operand(rsp, 4 * kPointerSize)); __ movq(Operand(rsp, 0 * kPointerSize), rax); GenerateFastApiCall(masm(), optimization, argc); diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc index b1900f9..0b342ff 100644 --- a/test/cctest/test-accessors.cc +++ b/test/cctest/test-accessors.cc @@ -1,4 +1,4 @@ -// Copyright 2009 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -116,6 +116,8 @@ static v8::Handle x_holder; static v8::Handle XGetter(Local name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(x_receiver, info.This()); CHECK_EQ(x_holder, info.Holder()); return v8_num(x_register); @@ -125,6 +127,8 @@ static v8::Handle XGetter(Local name, const AccessorInfo& info) { static void XSetter(Local name, Local value, const AccessorInfo& info) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(x_holder, info.This()); CHECK_EQ(x_holder, info.Holder()); x_register = value->Int32Value(); @@ -236,12 +240,15 @@ THREADED_TEST(HandleScopePop) { static v8::Handle CheckAccessorArgsCorrect(Local name, const AccessorInfo& info) { + CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); ApiTestFuzzer::Fuzz(); + CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); CHECK(info.This() == info.Holder()); CHECK(info.Data()->Equals(v8::String::New("data"))); return v8::Integer::New(17); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index a37b850..0232363 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -8608,6 +8608,8 @@ static void CheckInterceptorLoadIC(NamedPropertyGetter getter, static v8::Handle InterceptorLoadICGetter(Local name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + CHECK_EQ(isolate, info.GetIsolate()); CHECK_EQ(v8_str("data"), info.Data()); CHECK_EQ(v8_str("x"), name); return v8::Integer::New(42); @@ -9334,6 +9336,8 @@ static v8::Handle InterceptorCallICFastApi(Local name, static v8::Handle FastApiCallback_TrivialSignature( const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + CHECK_EQ(isolate, args.GetIsolate()); CHECK_EQ(args.This(), args.Holder()); CHECK(args.Data()->Equals(v8_str("method_data"))); return v8::Integer::New(args[0]->Int32Value() + 1); @@ -9342,6 +9346,8 @@ static v8::Handle FastApiCallback_TrivialSignature( static v8::Handle FastApiCallback_SimpleSignature( const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + CHECK_EQ(isolate, args.GetIsolate()); CHECK_EQ(args.This()->GetPrototype(), args.Holder()); CHECK(args.Data()->Equals(v8_str("method_data"))); // Note, we're using HasRealNamedProperty instead of Has to avoid -- 2.7.4