| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index bc1173b131550b03833f482610ee0a0932232a1a..9f44d180a4cafd1a6ec2f65d667efcef15e45ad8 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -102,7 +102,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
| ASSERT(is_done());
|
| code->set_stack_slots(GetStackSlotCount());
|
| code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
|
| - if (FLAG_weak_embedded_maps_in_optimized_code) {
|
| + if (FLAG_weak_embedded_maps_in_optimized_code &&
|
| + code->kind() == Code::OPTIMIZED_FUNCTION) {
|
| RegisterDependentCodeForEmbeddedMaps(code);
|
| }
|
| PopulateDeoptimizationData(code);
|
| @@ -2784,6 +2785,7 @@ void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
|
| __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx);
|
| } else {
|
| Register reg = ToRegister(instr->parameter_count());
|
| + __ SmiUntag(reg); // it is a smi
|
| Register return_addr_reg = reg.is(ecx) ? ebx : ecx;
|
| if (dynamic_frame_alignment && FLAG_debug_code) {
|
| ASSERT(extra_value_count == 2);
|
| @@ -3196,13 +3198,21 @@ void LCodeGen::DoLoadExternalArrayPointer(
|
|
|
| void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
|
| Register arguments = ToRegister(instr->arguments());
|
| - Register length = ToRegister(instr->length());
|
| - Operand index = ToOperand(instr->index());
|
| Register result = ToRegister(instr->result());
|
| - // There are two words between the frame pointer and the last argument.
|
| - // Subtracting from length accounts for one of them add one more.
|
| - __ sub(length, index);
|
| - __ mov(result, Operand(arguments, length, times_4, kPointerSize));
|
| + if (instr->length()->IsConstantOperand() &&
|
| + instr->index()->IsConstantOperand()) {
|
| + int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
|
| + int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
|
| + int index = (const_length - const_index) + 1;
|
| + __ mov(result, Operand(arguments, index * kPointerSize));
|
| + } else {
|
| + Register length = ToRegister(instr->length());
|
| + Operand index = ToOperand(instr->index());
|
| + // There are two words between the frame pointer and the last argument.
|
| + // Subtracting from length accounts for one of them add one more.
|
| + __ sub(length, index);
|
| + __ mov(result, Operand(arguments, length, times_4, kPointerSize));
|
| + }
|
| }
|
|
|
|
|
| @@ -4198,11 +4208,20 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
| ASSERT(ToRegister(instr->result()).is(eax));
|
| ASSERT(FLAG_optimize_constructed_arrays);
|
|
|
| - __ mov(ebx, instr->hydrogen()->property_cell());
|
| - Handle<Code> array_construct_code =
|
| - isolate()->builtins()->ArrayConstructCode();
|
| __ Set(eax, Immediate(instr->arity()));
|
| - CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr);
|
| + __ mov(ebx, instr->hydrogen()->property_cell());
|
| + Object* cell_value = instr->hydrogen()->property_cell()->value();
|
| + ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value());
|
| + if (instr->arity() == 0) {
|
| + ArrayNoArgumentConstructorStub stub(kind);
|
| + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
| + } else if (instr->arity() == 1) {
|
| + ArraySingleArgumentConstructorStub stub(kind);
|
| + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
| + } else {
|
| + ArrayNArgumentsConstructorStub stub(kind);
|
| + CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
| + }
|
| }
|
|
|
|
|
| @@ -4220,7 +4239,6 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
|
|
|
| void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| Register object = ToRegister(instr->object());
|
| - Register value = ToRegister(instr->value());
|
| int offset = instr->offset();
|
|
|
| if (!instr->transition().is_null()) {
|
| @@ -4247,8 +4265,25 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| SmiCheck check_needed =
|
| type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
|
| if (instr->is_in_object()) {
|
| - __ mov(FieldOperand(object, offset), value);
|
| + if (instr->value()->IsConstantOperand()) {
|
| + LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| + if (IsInteger32(operand_value)) {
|
| + int const_value = ToInteger32(operand_value);
|
| + __ mov(FieldOperand(object, offset), Immediate(const_value));
|
| + } else {
|
| + if (operand_value->IsRegister()) {
|
| + __ mov(FieldOperand(object, offset), ToRegister(operand_value));
|
| + } else {
|
| + Handle<Object> handle_value = ToHandle(operand_value);
|
| + __ mov(FieldOperand(object, offset), handle_value);
|
| + }
|
| + }
|
| + } else {
|
| + __ mov(FieldOperand(object, offset), ToRegister(instr->value()));
|
| + }
|
| +
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + Register value = ToRegister(instr->value());
|
| Register temp = ToRegister(instr->temp());
|
| // Update the write barrier for the object for in-object properties.
|
| __ RecordWriteField(object,
|
| @@ -4262,8 +4297,26 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| } else {
|
| Register temp = ToRegister(instr->temp());
|
| __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
|
| - __ mov(FieldOperand(temp, offset), value);
|
| +
|
| + if (instr->value()->IsConstantOperand()) {
|
| + LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| + if (IsInteger32(operand_value)) {
|
| + int const_value = ToInteger32(operand_value);
|
| + __ mov(FieldOperand(temp, offset), Immediate(const_value));
|
| + } else {
|
| + if (operand_value->IsRegister()) {
|
| + __ mov(FieldOperand(temp, offset), ToRegister(operand_value));
|
| + } else {
|
| + Handle<Object> handle_value = ToHandle(operand_value);
|
| + __ mov(FieldOperand(temp, offset), handle_value);
|
| + }
|
| + }
|
| + } else {
|
| + __ mov(FieldOperand(temp, offset), ToRegister(instr->value()));
|
| + }
|
| +
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + Register value = ToRegister(instr->value());
|
| // Update the write barrier for the properties array.
|
| // object is used as a scratch register.
|
| __ RecordWriteField(temp,
|
| @@ -4451,7 +4504,6 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
|
|
|
|
| void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| - Register value = ToRegister(instr->value());
|
| Register elements = ToRegister(instr->elements());
|
| Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
|
|
|
| @@ -4462,9 +4514,22 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| FAST_ELEMENTS,
|
| FixedArray::kHeaderSize - kHeapObjectTag,
|
| instr->additional_index());
|
| - __ mov(operand, value);
|
| + if (instr->value()->IsRegister()) {
|
| + __ mov(operand, ToRegister(instr->value()));
|
| + } else {
|
| + LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| + if (IsInteger32(operand_value)) {
|
| + int const_value = ToInteger32(operand_value);
|
| + __ mov(operand, Immediate(const_value));
|
| + } else {
|
| + Handle<Object> handle_value = ToHandle(operand_value);
|
| + __ mov(operand, handle_value);
|
| + }
|
| + }
|
|
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + ASSERT(instr->value()->IsRegister());
|
| + Register value = ToRegister(instr->value());
|
| ASSERT(!instr->key()->IsConstantOperand());
|
| HType type = instr->hydrogen()->value()->type();
|
| SmiCheck check_needed =
|
|
|