Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Unified Diff: src/ia32/lithium-codegen-ia32.cc

Issue 6322008: Version 3.0.10... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/lithium-codegen-ia32.cc
===================================================================
--- src/ia32/lithium-codegen-ia32.cc (revision 6437)
+++ src/ia32/lithium-codegen-ia32.cc (working copy)
@@ -1285,11 +1285,11 @@
NearLabel done;
Condition cc = TokenToCondition(instr->op(), instr->is_double());
- __ mov(ToRegister(result), Handle<Object>(Heap::true_value()));
+ __ mov(ToRegister(result), Factory::true_value());
__ j(cc, &done);
__ bind(&unordered);
- __ mov(ToRegister(result), Handle<Object>(Heap::false_value()));
+ __ mov(ToRegister(result), Factory::false_value());
__ bind(&done);
}
@@ -1320,10 +1320,10 @@
Register result = ToRegister(instr->result());
__ cmp(left, Operand(right));
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
NearLabel done;
__ j(equal, &done);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ bind(&done);
}
@@ -1348,10 +1348,10 @@
__ cmp(reg, Factory::null_value());
if (instr->is_strict()) {
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
NearLabel done;
__ j(equal, &done);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ bind(&done);
} else {
NearLabel true_value, false_value, done;
@@ -1368,10 +1368,10 @@
__ test(scratch, Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, &true_value);
__ bind(&false_value);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ jmp(&done);
__ bind(&true_value);
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
__ bind(&done);
}
}
@@ -1447,11 +1447,11 @@
__ j(true_cond, &is_true);
__ bind(&is_false);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ jmp(&done);
__ bind(&is_true);
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
__ bind(&done);
}
@@ -1479,10 +1479,10 @@
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ test(input, Immediate(kSmiTagMask));
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
NearLabel done;
__ j(zero, &done);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ bind(&done);
}
@@ -1507,7 +1507,6 @@
}
-
static Condition BranchCondition(HHasInstanceType* instr) {
InstanceType from = instr->from();
InstanceType to = instr->to();
@@ -1529,10 +1528,10 @@
__ j(zero, &is_false);
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
__ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
__ jmp(&done);
__ bind(&is_false);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ bind(&done);
}
@@ -1559,12 +1558,12 @@
Register result = ToRegister(instr->result());
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
__ test(FieldOperand(input, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask));
NearLabel done;
__ j(not_zero, &done);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ bind(&done);
}
@@ -1653,11 +1652,11 @@
__ j(not_equal, &is_false);
__ bind(&is_true);
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
__ jmp(&done);
__ bind(&is_false);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ bind(&done);
}
@@ -2221,11 +2220,12 @@
Label negative;
__ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
- // Check the sign of the argument. If the argument is positive,
- // just return it.
+ // Check the sign of the argument. If the argument is positive, just
+ // return it. We do not need to patch the stack since |input| and
+ // |result| are the same register and |input| will be restored
+ // unchanged by popping safepoint registers.
__ test(tmp, Immediate(HeapNumber::kSignMask));
__ j(not_zero, &negative);
- __ mov(tmp, input_reg);
__ jmp(&done);
__ bind(&negative);
@@ -2252,14 +2252,25 @@
__ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2);
__ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset));
__ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2);
+ __ mov(Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize), tmp);
__ bind(&done);
- __ mov(Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize), tmp);
-
__ PopSafepointRegisters();
}
+void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
+ Register input_reg = ToRegister(instr->InputAt(0));
+ __ test(input_reg, Operand(input_reg));
+ Label is_positive;
+ __ j(not_sign, &is_positive);
+ __ neg(input_reg);
+ __ test(input_reg, Operand(input_reg));
+ DeoptimizeIf(negative, instr->environment());
+ __ bind(&is_positive);
+}
+
+
void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
// Class for deferred case.
class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
@@ -2284,31 +2295,15 @@
__ subsd(scratch, input_reg);
__ pand(input_reg, scratch);
} else if (r.IsInteger32()) {
- Register input_reg = ToRegister(instr->InputAt(0));
- __ test(input_reg, Operand(input_reg));
- Label is_positive;
- __ j(not_sign, &is_positive);
- __ neg(input_reg);
- __ test(input_reg, Operand(input_reg));
- DeoptimizeIf(negative, instr->environment());
- __ bind(&is_positive);
+ EmitIntegerMathAbs(instr);
} else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred =
new DeferredMathAbsTaggedHeapNumber(this, instr);
- Label not_smi;
Register input_reg = ToRegister(instr->InputAt(0));
// Smi check.
__ test(input_reg, Immediate(kSmiTagMask));
__ j(not_zero, deferred->entry());
- __ test(input_reg, Operand(input_reg));
- Label is_positive;
- __ j(not_sign, &is_positive);
- __ neg(input_reg);
-
- __ test(input_reg, Operand(input_reg));
- DeoptimizeIf(negative, instr->environment());
-
- __ bind(&is_positive);
+ EmitIntegerMathAbs(instr);
__ bind(deferred->exit());
}
}
@@ -2651,6 +2646,151 @@
}
+void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
+ class DeferredStringCharCodeAt: public LDeferredCode {
+ public:
+ DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
+ private:
+ LStringCharCodeAt* instr_;
+ };
+
+ Register string = ToRegister(instr->string());
+ Register index = no_reg;
+ int const_index = -1;
+ if (instr->index()->IsConstantOperand()) {
+ const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+ STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
+ if (!Smi::IsValid(const_index)) {
+ // Guaranteed to be out of bounds because of the assert above.
+ // So the bounds check that must dominate this instruction must
+ // have deoptimized already.
+ if (FLAG_debug_code) {
+ __ Abort("StringCharCodeAt: out of bounds index.");
+ }
+ // No code needs to be generated.
+ return;
+ }
+ } else {
+ index = ToRegister(instr->index());
+ }
+ Register result = ToRegister(instr->result());
+
+ DeferredStringCharCodeAt* deferred =
+ new DeferredStringCharCodeAt(this, instr);
+
+ NearLabel flat_string, ascii_string, done;
+
+ // Fetch the instance type of the receiver into result register.
+ __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
+
+ // We need special handling for non-flat strings.
+ STATIC_ASSERT(kSeqStringTag == 0);
+ __ test(result, Immediate(kStringRepresentationMask));
+ __ j(zero, &flat_string);
+
+ // Handle non-flat strings.
+ __ test(result, Immediate(kIsConsStringMask));
+ __ j(zero, deferred->entry());
+
+ // ConsString.
+ // Check whether the right hand side is the empty string (i.e. if
+ // this is really a flat string in a cons string). If that is not
+ // the case we would rather go to the runtime system now to flatten
+ // the string.
+ __ cmp(FieldOperand(string, ConsString::kSecondOffset),
+ Immediate(Factory::empty_string()));
+ __ j(not_equal, deferred->entry());
+ // Get the first of the two strings and load its instance type.
+ __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
+ __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
+ __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
+ // If the first cons component is also non-flat, then go to runtime.
+ STATIC_ASSERT(kSeqStringTag == 0);
+ __ test(result, Immediate(kStringRepresentationMask));
+ __ j(not_zero, deferred->entry());
+
+ // Check for 1-byte or 2-byte string.
+ __ bind(&flat_string);
+ STATIC_ASSERT(kAsciiStringTag != 0);
+ __ test(result, Immediate(kStringEncodingMask));
+ __ j(not_zero, &ascii_string);
+
+ // 2-byte string.
+ // Load the 2-byte character code into the result register.
+ STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
+ if (instr->index()->IsConstantOperand()) {
+ __ movzx_w(result,
+ FieldOperand(string,
+ SeqTwoByteString::kHeaderSize + 2 * const_index));
+ } else {
+ __ movzx_w(result, FieldOperand(string,
+ index,
+ times_2,
+ SeqTwoByteString::kHeaderSize));
+ }
+ __ jmp(&done);
+
+ // ASCII string.
+ // Load the byte into the result register.
+ __ bind(&ascii_string);
+ if (instr->index()->IsConstantOperand()) {
+ __ movzx_b(result, FieldOperand(string,
+ SeqAsciiString::kHeaderSize + const_index));
+ } else {
+ __ movzx_b(result, FieldOperand(string,
+ index,
+ times_1,
+ SeqAsciiString::kHeaderSize));
+ }
+ __ bind(&done);
+ __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
+ Register string = ToRegister(instr->string());
+ Register result = ToRegister(instr->result());
+
+ // 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.
+ __ Set(result, Immediate(0));
+
+ __ PushSafepointRegisters();
+ __ push(string);
+ // Push the index as a smi. This is safe because of the checks in
+ // DoStringCharCodeAt above.
+ STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
+ if (instr->index()->IsConstantOperand()) {
+ int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+ __ push(Immediate(Smi::FromInt(const_index)));
+ } else {
+ Register index = ToRegister(instr->index());
+ __ SmiTag(index);
+ __ push(index);
+ }
+ __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
+ if (FLAG_debug_code) {
+ __ AbortIfNotSmi(eax);
+ }
+ __ SmiUntag(eax);
+ __ mov(Operand(esp, EspIndexForPushAll(result) * kPointerSize), eax);
+ __ PopSafepointRegisters();
+}
+
+
+void LCodeGen::DoStringLength(LStringLength* instr) {
+ Register string = ToRegister(instr->string());
+ Register result = ToRegister(instr->result());
+ __ mov(result, FieldOperand(string, String::kLengthOffset));
+}
+
+
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() || input->IsStackSlot());
@@ -3077,13 +3217,19 @@
InstanceType last = instr->hydrogen()->last();
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
- __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
- static_cast<int8_t>(first));
// If there is only one type in the interval check for equality.
if (first == last) {
+ __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
+ static_cast<int8_t>(first));
DeoptimizeIf(not_equal, instr->environment());
- } else {
+ } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) {
+ // String has a dedicated bit in instance type.
+ __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), kIsNotStringMask);
+ DeoptimizeIf(not_zero, instr->environment());
+ } else {
+ __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
+ static_cast<int8_t>(first));
DeoptimizeIf(below, instr->environment());
// Omit check for the last type.
if (last != LAST_TYPE) {
@@ -3292,11 +3438,11 @@
instr->type_literal());
__ j(final_branch_condition, &true_label);
__ bind(&false_label);
- __ mov(result, Handle<Object>(Heap::false_value()));
+ __ mov(result, Factory::false_value());
__ jmp(&done);
__ bind(&true_label);
- __ mov(result, Handle<Object>(Heap::true_value()));
+ __ mov(result, Factory::true_value());
__ bind(&done);
}
@@ -3341,9 +3487,9 @@
final_branch_condition = below;
} else if (type_name->Equals(Heap::boolean_symbol())) {
- __ cmp(input, Handle<Object>(Heap::true_value()));
+ __ cmp(input, Factory::true_value());
__ j(equal, true_label);
- __ cmp(input, Handle<Object>(Heap::false_value()));
+ __ cmp(input, Factory::false_value());
final_branch_condition = equal;
} else if (type_name->Equals(Heap::undefined_symbol())) {
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-gap-resolver-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698