summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/lithium-codegen-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/lithium-codegen-ia32.cc')
-rw-r--r--deps/v8/src/ia32/lithium-codegen-ia32.cc166
1 files changed, 94 insertions, 72 deletions
diff --git a/deps/v8/src/ia32/lithium-codegen-ia32.cc b/deps/v8/src/ia32/lithium-codegen-ia32.cc
index d93c27ad2..1d9e9421b 100644
--- a/deps/v8/src/ia32/lithium-codegen-ia32.cc
+++ b/deps/v8/src/ia32/lithium-codegen-ia32.cc
@@ -113,6 +113,10 @@ void LCodeGen::FinishCode(Handle<Code> code) {
prototype_maps_.at(i)->AddDependentCode(
DependentCode::kPrototypeCheckGroup, code);
}
+ for (int i = 0 ; i < transition_maps_.length(); i++) {
+ transition_maps_.at(i)->AddDependentCode(
+ DependentCode::kTransitionGroup, code);
+ }
}
@@ -1230,7 +1234,7 @@ void LCodeGen::DoModI(LModI* instr) {
__ and_(dividend, divisor - 1);
__ bind(&done);
} else {
- Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
+ Label done, remainder_eq_dividend, slow, both_positive;
Register left_reg = ToRegister(instr->left());
Register right_reg = ToRegister(instr->right());
Register result_reg = ToRegister(instr->result());
@@ -1266,23 +1270,10 @@ void LCodeGen::DoModI(LModI* instr) {
__ mov(scratch, right_reg);
__ sub(Operand(scratch), Immediate(1));
__ test(scratch, Operand(right_reg));
- __ j(not_zero, &do_subtraction, Label::kNear);
+ __ j(not_zero, &slow, Label::kNear);
__ and_(left_reg, Operand(scratch));
__ jmp(&remainder_eq_dividend, Label::kNear);
- __ bind(&do_subtraction);
- const int kUnfolds = 3;
- // Try a few subtractions of the dividend.
- __ mov(scratch, left_reg);
- for (int i = 0; i < kUnfolds; i++) {
- // Reduce the dividend by the divisor.
- __ sub(left_reg, Operand(right_reg));
- // Check if the dividend is less than the divisor.
- __ cmp(left_reg, Operand(right_reg));
- __ j(less, &remainder_eq_dividend, Label::kNear);
- }
- __ mov(left_reg, scratch);
-
// Slow case, using idiv instruction.
__ bind(&slow);
@@ -1915,16 +1906,24 @@ void LCodeGen::DoThrow(LThrow* instr) {
void LCodeGen::DoAddI(LAddI* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
- ASSERT(left->Equals(instr->result()));
- if (right->IsConstantOperand()) {
- __ add(ToOperand(left), ToInteger32Immediate(right));
+ if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
+ if (right->IsConstantOperand()) {
+ int32_t offset = ToInteger32(LConstantOperand::cast(right));
+ __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset));
+ } else {
+ Operand address(ToRegister(left), ToRegister(right), times_1, 0);
+ __ lea(ToRegister(instr->result()), address);
+ }
} else {
- __ add(ToRegister(left), ToOperand(right));
- }
-
- if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
- DeoptimizeIf(overflow, instr->environment());
+ if (right->IsConstantOperand()) {
+ __ add(ToOperand(left), ToInteger32Immediate(right));
+ } else {
+ __ add(ToRegister(left), ToOperand(right));
+ }
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
}
}
@@ -2956,13 +2955,27 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
+ int offset = instr->hydrogen()->offset();
Register object = ToRegister(instr->object());
+ if (FLAG_track_double_fields &&
+ instr->hydrogen()->representation().IsDouble()) {
+ if (CpuFeatures::IsSupported(SSE2)) {
+ CpuFeatureScope scope(masm(), SSE2);
+ XMMRegister result = ToDoubleRegister(instr->result());
+ __ movdbl(result, FieldOperand(object, offset));
+ } else {
+ PushX87DoubleOperand(FieldOperand(object, offset));
+ CurrentInstructionReturnsX87Result();
+ }
+ return;
+ }
+
Register result = ToRegister(instr->result());
if (instr->hydrogen()->is_in_object()) {
- __ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
+ __ mov(result, FieldOperand(object, offset));
} else {
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
- __ mov(result, FieldOperand(result, instr->hydrogen()->offset()));
+ __ mov(result, FieldOperand(result, offset));
}
}
@@ -3146,41 +3159,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
}
-void LCodeGen::DoLoadElements(LLoadElements* instr) {
- Register result = ToRegister(instr->result());
- Register input = ToRegister(instr->object());
- __ mov(result, FieldOperand(input, JSObject::kElementsOffset));
- if (FLAG_debug_code) {
- Label done, ok, fail;
- __ cmp(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(factory()->fixed_array_map()));
- __ j(equal, &done, Label::kNear);
- __ cmp(FieldOperand(result, HeapObject::kMapOffset),
- Immediate(factory()->fixed_cow_array_map()));
- __ j(equal, &done, Label::kNear);
- Register temp((result.is(eax)) ? ebx : eax);
- __ push(temp);
- __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
- __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset));
- __ and_(temp, Map::kElementsKindMask);
- __ shr(temp, Map::kElementsKindShift);
- __ cmp(temp, GetInitialFastElementsKind());
- __ j(less, &fail, Label::kNear);
- __ cmp(temp, TERMINAL_FAST_ELEMENTS_KIND);
- __ j(less_equal, &ok, Label::kNear);
- __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
- __ j(less, &fail, Label::kNear);
- __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
- __ j(less_equal, &ok, Label::kNear);
- __ bind(&fail);
- __ Abort("Check for fast or external elements failed.");
- __ bind(&ok);
- __ pop(temp);
- __ bind(&done);
- }
-}
-
-
void LCodeGen::DoLoadExternalArrayPointer(
LLoadExternalArrayPointer* instr) {
Register result = ToRegister(instr->result());
@@ -4213,8 +4191,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ Set(eax, Immediate(instr->arity()));
__ mov(ebx, instr->hydrogen()->property_cell());
- Object* cell_value = instr->hydrogen()->property_cell()->value();
- ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value());
+ ElementsKind kind = instr->hydrogen()->elements_kind();
if (instr->arity() == 0) {
ArrayNoArgumentConstructorStub stub(kind);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
@@ -4241,16 +4218,51 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
+ Representation representation = instr->representation();
+
Register object = ToRegister(instr->object());
+
int offset = instr->offset();
- if (!instr->transition().is_null()) {
+ Handle<Map> transition = instr->transition();
+
+ if (FLAG_track_fields && representation.IsSmi()) {
+ if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+ if (!IsInteger32(operand_value)) {
+ DeoptimizeIf(no_condition, instr->environment());
+ }
+ } else {
+ Register value = ToRegister(instr->value());
+ __ SmiTag(value);
+ if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+ }
+ } else if (FLAG_track_double_fields && representation.IsDouble()) {
+ ASSERT(transition.is_null());
+ ASSERT(instr->is_in_object());
+ ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
+ if (CpuFeatures::IsSupported(SSE2)) {
+ CpuFeatureScope scope(masm(), SSE2);
+ XMMRegister value = ToDoubleRegister(instr->value());
+ __ movdbl(FieldOperand(object, offset), value);
+ } else {
+ __ fstp_d(FieldOperand(object, offset));
+ }
+ return;
+ }
+
+ if (!transition.is_null()) {
+ if (transition->CanBeDeprecated()) {
+ transition_maps_.Add(transition, info()->zone());
+ }
if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
- __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
+ __ mov(FieldOperand(object, HeapObject::kMapOffset), transition);
} else {
Register temp = ToRegister(instr->temp());
Register temp_map = ToRegister(instr->temp_map());
- __ mov(temp_map, instr->transition());
+ __ mov(temp_map, transition);
__ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
// Update the write barrier for the map field.
__ RecordWriteField(object,
@@ -4286,6 +4298,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
__ mov(FieldOperand(write_register, offset), ToRegister(operand_value));
} else {
Handle<Object> handle_value = ToHandle(operand_value);
+ ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
__ mov(FieldOperand(write_register, offset), handle_value);
}
} else {
@@ -5459,6 +5472,8 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
} else {
mode = NUMBER_CANDIDATE_IS_SMI;
}
+ } else {
+ mode = NUMBER_CANDIDATE_IS_SMI;
}
}
@@ -6025,18 +6040,24 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
- Register size = ToRegister(instr->size());
Register result = ToRegister(instr->result());
- __ SmiTag(size);
- PushSafepointRegistersScope scope(this);
// TODO(3095996): Get rid of this. For now, we need to make the
// result register contain a valid pointer because it is already
// contained in the register pointer map.
- if (!size.is(result)) {
- __ StoreToSafepointRegisterSlot(result, size);
+ __ mov(result, Immediate(Smi::FromInt(0)));
+
+ PushSafepointRegistersScope scope(this);
+ if (instr->size()->IsRegister()) {
+ Register size = ToRegister(instr->size());
+ ASSERT(!size.is(result));
+ __ SmiTag(ToRegister(instr->size()));
+ __ push(size);
+ } else {
+ int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
+ __ push(Immediate(Smi::FromInt(size)));
}
- __ push(size);
+
if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
CallRuntimeFromDeferred(
Runtime::kAllocateInOldPointerSpace, 1, instr, instr->context());
@@ -6125,7 +6146,8 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
// Set up the parameters to the stub/runtime call and pick the right
// runtime function or stub to call.
int properties_count = instr->hydrogen()->constant_properties_length() / 2;
- if (instr->hydrogen()->depth() > 1) {
+ if ((FLAG_track_double_fields && instr->hydrogen()->may_store_doubles()) ||
+ instr->hydrogen()->depth() > 1) {
__ PushHeapObject(literals);
__ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
__ push(Immediate(constant_properties));