diff options
Diffstat (limited to 'deps/v8/src/ia32/stub-cache-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/stub-cache-ia32.cc | 183 |
1 files changed, 135 insertions, 48 deletions
diff --git a/deps/v8/src/ia32/stub-cache-ia32.cc b/deps/v8/src/ia32/stub-cache-ia32.cc index 3906623a58..28e043d641 100644 --- a/deps/v8/src/ia32/stub-cache-ia32.cc +++ b/deps/v8/src/ia32/stub-cache-ia32.cc @@ -27,7 +27,7 @@ #include "v8.h" -#if defined(V8_TARGET_ARCH_IA32) +#if V8_TARGET_ARCH_IA32 #include "ic-inl.h" #include "codegen.h" @@ -503,7 +503,12 @@ static void GenerateFastApiCall(MacroAssembler* masm, 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. @@ -517,20 +522,26 @@ static void GenerateFastApiCall(MacroAssembler* masm, __ 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); @@ -753,16 +764,16 @@ static void GenerateCheckPropertyCell(MacroAssembler* masm, Handle<Name> name, Register scratch, Label* miss) { - Handle<JSGlobalPropertyCell> cell = + Handle<PropertyCell> cell = GlobalObject::EnsurePropertyCell(global, name); ASSERT(cell->value()->IsTheHole()); Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); if (Serializer::enabled()) { __ mov(scratch, Immediate(cell)); - __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), + __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), Immediate(the_hole)); } else { - __ cmp(Operand::Cell(cell), Immediate(the_hole)); + __ cmp(Operand::ForCell(cell), Immediate(the_hole)); } __ j(not_equal, miss); } @@ -839,8 +850,14 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, Register storage_reg = name_reg; - if (FLAG_track_fields && representation.IsSmi()) { - __ JumpIfNotSmi(value_reg, miss_restore_name); + if (details.type() == CONSTANT_FUNCTION) { + Handle<HeapObject> constant( + HeapObject::cast(descriptors->GetValue(descriptor))); + __ LoadHeapObject(scratch1, constant); + __ cmp(value_reg, scratch1); + __ j(not_equal, miss_restore_name); + } else if (FLAG_track_fields && representation.IsSmi()) { + __ JumpIfNotSmi(value_reg, miss_restore_name); } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { __ JumpIfSmi(value_reg, miss_restore_name); } else if (FLAG_track_double_fields && representation.IsDouble()) { @@ -884,7 +901,8 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); // Perform map transition for the receiver if necessary. - if (object->map()->unused_property_fields() == 0) { + if (details.type() == FIELD && + object->map()->unused_property_fields() == 0) { // The properties must be extended before we can store the value. // We jump to a runtime call that extends the properties array. __ pop(scratch1); // Return address. @@ -913,6 +931,12 @@ void StubCompiler::GenerateStoreTransition(MacroAssembler* masm, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); + if (details.type() == CONSTANT_FUNCTION) { + ASSERT(value_reg.is(eax)); + __ ret(0); + return; + } + int index = transition->instance_descriptors()->GetFieldIndex( transition->LastAdded()); @@ -1406,7 +1430,9 @@ void BaseLoadStubCompiler::GenerateLoadCallback( // 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 = @@ -1422,7 +1448,13 @@ void BaseLoadStubCompiler::GenerateLoadCallback( // 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); @@ -1565,15 +1597,15 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, void CallStubCompiler::GenerateLoadFunctionFromCell( - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, Label* miss) { // Get the value from the cell. if (Serializer::enabled()) { __ mov(edi, Immediate(cell)); - __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); + __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); } else { - __ mov(edi, Operand::Cell(cell)); + __ mov(edi, Operand::ForCell(cell)); } // Check that the cell contains the same function. @@ -1664,12 +1696,59 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, } +Handle<Code> CallStubCompiler::CompileArrayCodeCall( + Handle<Object> object, + Handle<JSObject> holder, + Handle<Cell> cell, + Handle<JSFunction> function, + Handle<String> name, + Code::StubType type) { + Label miss; + + // Check that function is still array + const int argc = arguments().immediate(); + GenerateNameCheck(name, &miss); + + if (cell.is_null()) { + // Get the receiver from the stack. + __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); + + // Check that the receiver isn't a smi. + __ JumpIfSmi(edx, &miss); + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, + name, &miss); + } else { + ASSERT(cell->value() == *function); + GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, + &miss); + GenerateLoadFunctionFromCell(cell, function, &miss); + } + + Handle<Smi> kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); + Handle<Cell> kind_feedback_cell = + isolate()->factory()->NewCell(kind); + __ mov(eax, Immediate(argc)); + __ mov(ebx, kind_feedback_cell); + __ mov(edi, function); + + ArrayConstructorStub stub(isolate()); + __ TailCallStub(&stub); + + __ bind(&miss); + GenerateMissBranch(); + + // Return the generated code. + return GetCode(type, name); +} + + Handle<Code> CallStubCompiler::CompileArrayPushCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : name // -- esp[0] : return address @@ -1918,16 +1997,17 @@ Handle<Code> CallStubCompiler::CompileArrayPushCall( GenerateMissBranch(); // Return the generated code. - return GetCode(function); + return GetCode(type, name); } Handle<Code> CallStubCompiler::CompileArrayPopCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : name // -- esp[0] : return address @@ -2000,16 +2080,17 @@ Handle<Code> CallStubCompiler::CompileArrayPopCall( GenerateMissBranch(); // Return the generated code. - return GetCode(function); + return GetCode(type, name); } Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : function name // -- esp[0] : return address @@ -2084,16 +2165,17 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( GenerateMissBranch(); // Return the generated code. - return GetCode(function); + return GetCode(type, name); } Handle<Code> CallStubCompiler::CompileStringCharAtCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : function name // -- esp[0] : return address @@ -2170,16 +2252,17 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall( GenerateMissBranch(); // Return the generated code. - return GetCode(function); + return GetCode(type, name); } Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : function name // -- esp[0] : return address @@ -2246,16 +2329,17 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( GenerateMissBranch(); // Return the generated code. - return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); + return GetCode(type, name); } Handle<Code> CallStubCompiler::CompileMathFloorCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : name // -- esp[0] : return address @@ -2377,16 +2461,17 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall( GenerateMissBranch(); // Return the generated code. - return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); + return GetCode(type, name); } Handle<Code> CallStubCompiler::CompileMathAbsCall( Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, - Handle<String> name) { + Handle<String> name, + Code::StubType type) { // ----------- S t a t e ------------- // -- ecx : name // -- esp[0] : return address @@ -2483,7 +2568,7 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall( GenerateMissBranch(); // Return the generated code. - return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); + return GetCode(type, name); } @@ -2491,7 +2576,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall( const CallOptimization& optimization, Handle<Object> object, Handle<JSObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<Cell> cell, Handle<JSFunction> function, Handle<String> name) { ASSERT(optimization.is_simple_api_call()); @@ -2673,8 +2758,9 @@ Handle<Code> CallStubCompiler::CompileCallConstant( if (HasCustomCallGenerator(function)) { Handle<Code> code = CompileCustomCall(object, holder, - Handle<JSGlobalPropertyCell>::null(), - function, Handle<String>::cast(name)); + Handle<Cell>::null(), + function, Handle<String>::cast(name), + Code::CONSTANT_FUNCTION); // A null handle means bail out to the regular compiler code below. if (!code.is_null()) return code; } @@ -2752,7 +2838,7 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, Handle<Code> CallStubCompiler::CompileCallGlobal( Handle<JSObject> object, Handle<GlobalObject> holder, - Handle<JSGlobalPropertyCell> cell, + Handle<PropertyCell> cell, Handle<JSFunction> function, Handle<Name> name) { // ----------- S t a t e ------------- @@ -2765,7 +2851,8 @@ Handle<Code> CallStubCompiler::CompileCallGlobal( if (HasCustomCallGenerator(function)) { Handle<Code> code = CompileCustomCall( - object, holder, cell, function, Handle<String>::cast(name)); + 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; } @@ -2935,7 +3022,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor( Handle<Code> StoreStubCompiler::CompileStoreGlobal( Handle<GlobalObject> object, - Handle<JSGlobalPropertyCell> cell, + Handle<PropertyCell> cell, Handle<Name> name) { Label miss; @@ -2947,7 +3034,7 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal( // Compute the cell operand to use. __ mov(scratch1(), Immediate(cell)); Operand cell_operand = - FieldOperand(scratch1(), JSGlobalPropertyCell::kValueOffset); + FieldOperand(scratch1(), PropertyCell::kValueOffset); // Check that the value in the cell is not the hole. If it is, this // cell could have been deleted and reintroducing the global needs @@ -3108,7 +3195,7 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, Handle<Code> LoadStubCompiler::CompileLoadGlobal( Handle<JSObject> object, Handle<GlobalObject> global, - Handle<JSGlobalPropertyCell> cell, + Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { Label success, miss; @@ -3119,9 +3206,9 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal( // Get the value from the cell. if (Serializer::enabled()) { __ mov(eax, Immediate(cell)); - __ mov(eax, FieldOperand(eax, JSGlobalPropertyCell::kValueOffset)); + __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); } else { - __ mov(eax, Operand::Cell(cell)); + __ mov(eax, Operand::ForCell(cell)); } // Check for deleted property if property can actually be deleted. |