Chromium Code Reviews| Index: src/codegen-ia32.cc |
| =================================================================== |
| --- src/codegen-ia32.cc (revision 405) |
| +++ src/codegen-ia32.cc (working copy) |
| @@ -64,7 +64,7 @@ |
| Expression* expression() const { return expression_; } |
| Type type() const { return type_; } |
| - void set_type(Type value) { |
| + void set_type(Type value) { |
| ASSERT(type_ == ILLEGAL); |
| type_ = value; |
| } |
| @@ -144,8 +144,10 @@ |
| Handle<Script> script, |
| bool is_eval); |
| - MacroAssembler* masm() { return masm_; } |
| + MacroAssembler* masm() { return masm_; } |
| + Scope* scope() const { return scope_; } |
| + |
| CodeGenState* state() { return state_; } |
| void set_state(CodeGenState* state) { state_ = state; } |
| @@ -167,7 +169,7 @@ |
| Ia32CodeGenerator(int buffer_size, |
| Handle<Script> script, |
| bool is_eval); |
| - virtual ~Ia32CodeGenerator() { delete masm_; } |
| + virtual ~Ia32CodeGenerator() { delete masm_; } |
| // Main code generation function |
| void GenCode(FunctionLiteral* fun); |
| @@ -191,13 +193,14 @@ |
| // Support functions for accessing parameters. Static versions can |
| // require some code generator state to be passed in as arguments. |
| - static Operand ParameterOperand(Scope* scope, int index) { |
| - ASSERT(-2 <= index && index < scope->num_parameters()); |
| - return Operand(ebp, (1 + scope->num_parameters() - index) * kPointerSize); |
| + static Operand ParameterOperand(const CodeGenerator* cgen, int index) { |
|
Kasper Lund
2008/10/02 08:57:58
Extra whitespace at end of line?
|
| + int num_parameters = cgen->scope()->num_parameters(); |
| + ASSERT(-2 <= index && index < num_parameters); |
| + return Operand(ebp, (1 + num_parameters - index) * kPointerSize); |
| } |
| Operand ParameterOperand(int index) const { |
| - return ParameterOperand(scope_, index); |
| + return ParameterOperand(this, index); |
| } |
| Operand ReceiverOperand() const { return ParameterOperand(-1); } |
| @@ -210,13 +213,12 @@ |
| return Operand(context, Context::SlotOffset(index)); |
| } |
| - static Operand SlotOperand(MacroAssembler* masm, |
| - Scope* scope, |
| + static Operand SlotOperand(CodeGenerator* cgen, |
| Slot* slot, |
| Register tmp); |
| Operand SlotOperand(Slot* slot, Register tmp) { |
| - return SlotOperand(masm_, scope_, slot, tmp); |
| + return SlotOperand(this, slot, tmp); |
| } |
| void LoadCondition(Expression* x, |
| @@ -254,14 +256,14 @@ |
| void SetValue(Reference* ref) { |
| ASSERT(!has_cc()); |
| ASSERT(!ref->is_illegal()); |
| - ref->expression()->GenerateStoreCode(masm_, scope_, ref, NOT_CONST_INIT); |
| + ref->expression()->GenerateStoreCode(this, ref, NOT_CONST_INIT); |
| } |
| // Same as SetValue, used to set the initial value of a constant. |
| void InitConst(Reference* ref) { |
| ASSERT(!has_cc()); |
| ASSERT(!ref->is_illegal()); |
| - ref->expression()->GenerateStoreCode(masm_, scope_, ref, CONST_INIT); |
| + ref->expression()->GenerateStoreCode(this, ref, CONST_INIT); |
| } |
| // Generate code to fetch a value from a property of a reference. The |
| @@ -273,7 +275,7 @@ |
| // stored value is expected on top of the expression stack, with the |
| // reference immediately below it. The expression stack is left |
| // unchanged. |
| - static void SetReferenceProperty(MacroAssembler* masm, |
| + static void SetReferenceProperty(CodeGenerator* cgen, |
| Reference* ref, |
| Expression* key); |
| @@ -423,9 +425,8 @@ |
| // ----------------------------------------------------------------------------- |
| // Ia32CodeGenerator implementation |
| -#define __ masm_-> |
| +#define __ masm_-> |
| - |
| Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit, |
| Handle<Script> script, |
| bool is_eval) { |
| @@ -731,8 +732,10 @@ |
| } |
| -Operand Ia32CodeGenerator::SlotOperand(MacroAssembler* masm, |
| - Scope* scope, |
| +#undef __ |
| +#define __ masm-> |
| + |
| +Operand Ia32CodeGenerator::SlotOperand(CodeGenerator* cgen, |
| Slot* slot, |
| Register tmp) { |
| // Currently, this assertion will fail if we try to assign to |
| @@ -746,27 +749,29 @@ |
| ASSERT(slot != NULL); |
| int index = slot->index(); |
| switch (slot->type()) { |
| - case Slot::PARAMETER: return ParameterOperand(scope, index); |
| + case Slot::PARAMETER: return ParameterOperand(cgen, index); |
| case Slot::LOCAL: { |
| - ASSERT(0 <= index && index < scope->num_stack_slots()); |
| + ASSERT(0 <= index && index < cgen->scope()->num_stack_slots()); |
| const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; |
| return Operand(ebp, kLocal0Offset - index * kPointerSize); |
| } |
| case Slot::CONTEXT: { |
| + MacroAssembler* masm = cgen->masm(); |
| // Follow the context chain if necessary. |
| ASSERT(!tmp.is(esi)); // do not overwrite context register |
| Register context = esi; |
| - int chain_length = scope->ContextChainLength(slot->var()->scope()); |
| + int chain_length = |
| + cgen->scope()->ContextChainLength(slot->var()->scope()); |
| for (int i = chain_length; i-- > 0;) { |
| // Load the closure. |
| // (All contexts, even 'with' contexts, have a closure, |
| // and it is the same for all contexts inside a function. |
| // There is no need to go to the function context first.) |
| - masm->mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); |
| + __ mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); |
| // Load the function context (which is the incoming, outer context). |
| - masm->mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset)); |
| + __ mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset)); |
| context = tmp; |
| } |
| // We may have a 'with' context now. Get the function context. |
| @@ -776,7 +781,7 @@ |
| // cause the function context of a function context is itself. Before |
| // deleting this mov we should try to create a counter-example first, |
| // though...) |
| - masm->mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX)); |
| + __ mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX)); |
| return ContextOperand(tmp, index); |
| } |
| @@ -787,6 +792,9 @@ |
| } |
| +#undef __ |
| +#define __ masm_-> |
| + |
| // Loads a value on TOS. If it is a boolean value, the result may have been |
| // (partially) translated into branches, or it may have set the condition code |
| // register. If force_cc is set, the value is forced to set the condition code |
| @@ -951,49 +959,52 @@ |
| } |
| -void Property::GenerateStoreCode(MacroAssembler* masm, |
| - Scope* scope, |
| +#undef __ |
| +#define __ masm-> |
| + |
| +void Property::GenerateStoreCode(CodeGenerator* cgen, |
| Reference* ref, |
| InitState init_state) { |
| + MacroAssembler* masm = cgen->masm(); |
| Comment cmnt(masm, "[ Store to Property"); |
| - masm->RecordPosition(position()); |
| - Ia32CodeGenerator::SetReferenceProperty(masm, ref, key()); |
| + __ RecordPosition(position()); |
| + Ia32CodeGenerator::SetReferenceProperty(cgen, ref, key()); |
| } |
| -void VariableProxy::GenerateStoreCode(MacroAssembler* masm, |
| - Scope* scope, |
| +void VariableProxy::GenerateStoreCode(CodeGenerator* cgen, |
| Reference* ref, |
| InitState init_state) { |
| + MacroAssembler* masm = cgen->masm(); |
| Comment cmnt(masm, "[ Store to VariableProxy"); |
| Variable* node = var(); |
| Expression* expr = node->rewrite(); |
| if (expr != NULL) { |
| - expr->GenerateStoreCode(masm, scope, ref, init_state); |
| + expr->GenerateStoreCode(cgen, ref, init_state); |
| } else { |
| ASSERT(node->is_global()); |
| if (node->AsProperty() != NULL) { |
| - masm->RecordPosition(node->AsProperty()->position()); |
| + __ RecordPosition(node->AsProperty()->position()); |
| } |
| - Ia32CodeGenerator::SetReferenceProperty(masm, ref, |
| - new Literal(node->name())); |
| + Expression* key = new Literal(node->name()); |
| + Ia32CodeGenerator::SetReferenceProperty(cgen, ref, key); |
| } |
| } |
| -void Slot::GenerateStoreCode(MacroAssembler* masm, |
| - Scope* scope, |
| +void Slot::GenerateStoreCode(CodeGenerator* cgen, |
| Reference* ref, |
| InitState init_state) { |
| + MacroAssembler* masm = cgen->masm(); |
| Comment cmnt(masm, "[ Store to Slot"); |
| if (type() == Slot::LOOKUP) { |
| ASSERT(var()->mode() == Variable::DYNAMIC); |
| // For now, just do a runtime call. |
| - masm->push(Operand(esi)); |
| - masm->push(Immediate(var()->name())); |
| + __ push(esi); |
| + __ push(Immediate(var()->name())); |
| if (init_state == CONST_INIT) { |
| // Same as the case for a normal store, but ignores attribute |
| @@ -1010,13 +1021,13 @@ |
| // the expression operands are defined and valid, and thus we need the |
| // split into 2 operations: declaration of the context slot followed |
| // by initialization. |
| - masm->CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
| + __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
| } else { |
| - masm->CallRuntime(Runtime::kStoreContextSlot, 3); |
| + __ CallRuntime(Runtime::kStoreContextSlot, 3); |
| } |
| // Storing a variable must keep the (new) value on the expression |
| // stack. This is necessary for compiling assignment expressions. |
| - masm->push(eax); |
| + __ push(eax); |
| } else { |
| ASSERT(var()->mode() != Variable::DYNAMIC); |
| @@ -1028,9 +1039,9 @@ |
| // still contains 'the hole' value). When the assignment is executed, |
| // the code is identical to a normal store (see below). |
| Comment cmnt(masm, "[ Init const"); |
| - masm->mov(eax, Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx)); |
| - masm->cmp(eax, Factory::the_hole_value()); |
| - masm->j(not_equal, &exit); |
| + __ mov(eax, Ia32CodeGenerator::SlotOperand(cgen, this, ecx)); |
| + __ cmp(eax, Factory::the_hole_value()); |
| + __ j(not_equal, &exit); |
| } |
| // We must execute the store. |
| @@ -1042,24 +1053,21 @@ |
| // Variable::CONST because of const declarations which will initialize |
| // consts to 'the hole' value and by doing so, end up calling this |
| // code. |
| - masm->pop(eax); |
| - masm->mov(Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx), eax); |
| - masm->push(eax); // RecordWrite may destroy the value in eax. |
| + __ pop(eax); |
| + __ mov(Ia32CodeGenerator::SlotOperand(cgen, this, ecx), eax); |
| + __ push(eax); // RecordWrite may destroy the value in eax. |
| if (type() == Slot::CONTEXT) { |
| // ecx is loaded with context when calling SlotOperand above. |
| int offset = FixedArray::kHeaderSize + index() * kPointerSize; |
| - masm->RecordWrite(ecx, offset, eax, ebx); |
| + __ RecordWrite(ecx, offset, eax, ebx); |
| } |
| // If we definitely did not jump over the assignment, we do not need to |
| // bind the exit label. Doing so can defeat peephole optimization. |
| - if (init_state == CONST_INIT) masm->bind(&exit); |
| + if (init_state == CONST_INIT) __ bind(&exit); |
| } |
| } |
| -#undef __ |
| -#define __ masm-> |
| - |
| class ToBooleanStub: public CodeStub { |
| public: |
| ToBooleanStub() { } |
| @@ -1138,10 +1146,10 @@ |
| __ ret(1 * kPointerSize); |
| } |
| + |
| #undef __ |
| -#define __ masm_-> |
| +#define __ masm_-> |
| - |
| // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and |
| // convert it to a boolean in the condition code register or jump to |
| // 'false_target'/'true_target' as appropriate. |
| @@ -1226,13 +1234,16 @@ |
| } |
| -void Ia32CodeGenerator::SetReferenceProperty(MacroAssembler* masm, |
| +#undef __ |
| +#define __ masm-> |
| + |
| +void Ia32CodeGenerator::SetReferenceProperty(CodeGenerator* cgen, |
| Reference* ref, |
| Expression* key) { |
| ASSERT(!ref->is_illegal()); |
| - Reference::Type type = ref->type(); |
| + MacroAssembler* masm = cgen->masm(); |
| - if (type == Reference::NAMED) { |
| + if (ref->type() == Reference::NAMED) { |
| // Compute the name of the property. |
| Literal* literal = key->AsLiteral(); |
| Handle<String> name(String::cast(*literal->handle())); |
| @@ -1240,28 +1251,24 @@ |
| // Call the appropriate IC code. |
| Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| // TODO(1222589): Make the IC grab the values from the stack. |
| - masm->pop(eax); |
| + __ pop(eax); |
| // Setup the name register. |
| - masm->Set(ecx, Immediate(name)); |
| - masm->call(ic, RelocInfo::CODE_TARGET); |
| + __ Set(ecx, Immediate(name)); |
| + __ call(ic, RelocInfo::CODE_TARGET); |
| } else { |
| // Access keyed property. |
| - ASSERT(type == Reference::KEYED); |
| + ASSERT(ref->type() == Reference::KEYED); |
| // Call IC code. |
| Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| // TODO(1222589): Make the IC grab the values from the stack. |
| - masm->pop(eax); |
| - masm->call(ic, RelocInfo::CODE_TARGET); |
| + __ pop(eax); |
| + __ call(ic, RelocInfo::CODE_TARGET); |
| } |
| - masm->push(eax); // IC call leaves result in eax, push it out |
| + __ push(eax); // IC call leaves result in eax, push it out |
| } |
| -#undef __ |
| -#define __ masm-> |
| - |
| - |
| class FloatingPointHelper : public AllStatic { |
| public: |
| // Code pattern for loading floating point values. Input values must |
| @@ -1771,10 +1778,6 @@ |
| } |
| -#undef __ |
| -#define __ masm-> |
| - |
| - |
| void UnarySubStub::Generate(MacroAssembler* masm) { |
| Label undo; |
| Label slow; |
| @@ -1827,7 +1830,7 @@ |
| __ bind(&done); |
| - masm->StubReturn(1); |
| + __ StubReturn(1); |
| } |
| @@ -1926,9 +1929,8 @@ |
| #undef __ |
| -#define __ masm_-> |
| +#define __ masm_-> |
| - |
| void Ia32CodeGenerator::GenericBinaryOperation(Token::Value op, |
| OverwriteMode overwrite_mode) { |
| Comment cmnt(masm_, "[ BinaryOperation"); |
| @@ -2365,7 +2367,7 @@ |
| #undef __ |
| -#define __ masm-> |
| +#define __ masm-> |
| class CompareStub: public CodeStub { |
| public: |
| @@ -2481,9 +2483,8 @@ |
| #undef __ |
| -#define __ masm_-> |
| +#define __ masm_-> |
| - |
| void Ia32CodeGenerator::Comparison(Condition cc, bool strict) { |
| // Strict only makes sense for equality comparisons. |
| ASSERT(!strict || cc == equal); |
| @@ -2592,36 +2593,42 @@ |
| }; |
| +#undef __ |
| +#define __ masm-> |
| + |
| void CallFunctionStub::Generate(MacroAssembler* masm) { |
| Label slow; |
| // Get the function to call from the stack. |
| // +2 ~ receiver, return address |
| - masm->mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); |
| + __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); |
| // Check that the function really is a JavaScript function. |
| - masm->test(edi, Immediate(kSmiTagMask)); |
| - masm->j(zero, &slow, not_taken); |
| + __ test(edi, Immediate(kSmiTagMask)); |
| + __ j(zero, &slow, not_taken); |
| // Get the map. |
| - masm->mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); |
| - masm->movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| - masm->cmp(ecx, JS_FUNCTION_TYPE); |
| - masm->j(not_equal, &slow, not_taken); |
| + __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); |
| + __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| + __ cmp(ecx, JS_FUNCTION_TYPE); |
| + __ j(not_equal, &slow, not_taken); |
| // Fast-case: Just invoke the function. |
| ParameterCount actual(argc_); |
| - masm->InvokeFunction(edi, actual, JUMP_FUNCTION); |
| + __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
| // Slow-case: Non-function called. |
| - masm->bind(&slow); |
| - masm->Set(eax, Immediate(argc_)); |
| - masm->Set(ebx, Immediate(0)); |
| - masm->GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| + __ bind(&slow); |
| + __ Set(eax, Immediate(argc_)); |
| + __ Set(ebx, Immediate(0)); |
| + __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
| - masm->jmp(adaptor, RelocInfo::CODE_TARGET); |
| + __ jmp(adaptor, RelocInfo::CODE_TARGET); |
| } |
| +#undef __ |
| +#define __ masm_-> |
| + |
| // Call the function just below TOS on the stack with the given |
| // arguments. The receiver is the TOS. |
| void Ia32CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
| @@ -4628,9 +4635,8 @@ |
| #undef __ |
| -#define __ masm-> |
| +#define __ masm-> |
| - |
| class RevertToNumberStub: public CodeStub { |
| public: |
| explicit RevertToNumberStub(bool is_increment) |
| @@ -4733,9 +4739,8 @@ |
| #undef __ |
| -#define __ masm_-> |
| +#define __ masm_-> |
| - |
| void CountOperationDeferred::Generate() { |
| if (is_postfix_) { |
| RevertToNumberStub to_number_stub(is_increment_); |
| @@ -5171,9 +5176,8 @@ |
| #undef __ |
| -#define __ masm-> |
| +#define __ masm-> |
| - |
| void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
| ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code |
| ExternalReference handler_address(Top::k_handler_address); |