| Index: src/ia32/stub-cache-ia32.cc
|
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
|
| index 3906623a586a17e4e71c0d8ecbfc6244c60e02dd..1a51016b831a3d1fa612f64b40f25cd76d6fd7b5 100644
|
| --- a/src/ia32/stub-cache-ia32.cc
|
| +++ b/src/ia32/stub-cache-ia32.cc
|
| @@ -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.
|
|
|