Version 3.17.7
Limited recursion in regexp compilation by a budget. (Chromium issue 178790)
ES6 symbols: Implemented Symbol intrinsic and basic functionality (issue 2158)
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@13808 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 58bdc89..0f2d32b 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -2509,12 +2509,12 @@
__ mov(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset));
__ mov(temp, FieldOperand(temp,
SharedFunctionInfo::kInstanceClassNameOffset));
- // The class name we are testing against is a symbol because it's a literal.
- // The name in the constructor is a symbol because of the way the context is
- // booted. This routine isn't expected to work for random API-created
+ // The class name we are testing against is internalized since it's a literal.
+ // The name in the constructor is internalized because of the way the context
+ // is booted. This routine isn't expected to work for random API-created
// classes and it doesn't have to because you can't access it with natives
- // syntax. Since both sides are symbols it is sufficient to use an identity
- // comparison.
+ // syntax. Since both sides are internalized it is sufficient to use an
+ // identity comparison.
__ cmp(temp, class_name);
// End with the answer in the z flag.
}
@@ -3733,77 +3733,64 @@
}
}
-void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
+void LCodeGen::DoMathRound(LMathRound* instr) {
CpuFeatures::Scope scope(SSE2);
Register output_reg = ToRegister(instr->result());
XMMRegister input_reg = ToDoubleRegister(instr->value());
XMMRegister xmm_scratch = xmm0;
+ XMMRegister input_temp = ToDoubleRegister(instr->temp());
ExternalReference one_half = ExternalReference::address_of_one_half();
ExternalReference minus_one_half =
ExternalReference::address_of_minus_one_half();
- bool minus_zero_check =
- instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
+ Label done, round_to_zero, below_one_half, do_not_compensate;
__ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
+ __ ucomisd(xmm_scratch, input_reg);
+ __ j(above, &below_one_half);
- if (CpuFeatures::IsSupported(SSE4_1) && !minus_zero_check) {
- CpuFeatures::Scope scope(SSE4_1);
+ // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x).
+ __ addsd(xmm_scratch, input_reg);
+ __ cvttsd2si(output_reg, Operand(xmm_scratch));
+ // Overflow is signalled with minint.
+ __ cmp(output_reg, 0x80000000u);
+ __ RecordComment("D2I conversion overflow");
+ DeoptimizeIf(equal, instr->environment());
+ __ jmp(&done);
- __ addsd(xmm_scratch, input_reg);
- __ roundsd(xmm_scratch, xmm_scratch, Assembler::kRoundDown);
- __ cvttsd2si(output_reg, Operand(xmm_scratch));
- // Overflow is signalled with minint.
- __ cmp(output_reg, 0x80000000u);
- __ RecordComment("D2I conversion overflow");
- DeoptimizeIf(equal, instr->environment());
- } else {
- Label done, round_to_zero, below_one_half, do_not_compensate;
- __ ucomisd(xmm_scratch, input_reg);
- __ j(above, &below_one_half);
+ __ bind(&below_one_half);
+ __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half));
+ __ ucomisd(xmm_scratch, input_reg);
+ __ j(below_equal, &round_to_zero);
- // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x).
- __ addsd(xmm_scratch, input_reg);
- __ cvttsd2si(output_reg, Operand(xmm_scratch));
- // Overflow is signalled with minint.
- __ cmp(output_reg, 0x80000000u);
- __ RecordComment("D2I conversion overflow");
- DeoptimizeIf(equal, instr->environment());
- __ jmp(&done);
+ // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
+ // compare and compensate.
+ __ movsd(input_temp, input_reg); // Do not alter input_reg.
+ __ subsd(input_temp, xmm_scratch);
+ __ cvttsd2si(output_reg, Operand(input_temp));
+ // Catch minint due to overflow, and to prevent overflow when compensating.
+ __ cmp(output_reg, 0x80000000u);
+ __ RecordComment("D2I conversion overflow");
+ DeoptimizeIf(equal, instr->environment());
- __ bind(&below_one_half);
- __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half));
- __ ucomisd(xmm_scratch, input_reg);
- __ j(below_equal, &round_to_zero);
+ __ cvtsi2sd(xmm_scratch, output_reg);
+ __ ucomisd(xmm_scratch, input_temp);
+ __ j(equal, &done);
+ __ sub(output_reg, Immediate(1));
+ // No overflow because we already ruled out minint.
+ __ jmp(&done);
- // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
- // compare and compensate.
- __ subsd(input_reg, xmm_scratch);
- __ cvttsd2si(output_reg, Operand(input_reg));
- // Catch minint due to overflow, and to prevent overflow when compensating.
- __ cmp(output_reg, 0x80000000u);
- __ RecordComment("D2I conversion overflow");
- DeoptimizeIf(equal, instr->environment());
-
- __ cvtsi2sd(xmm_scratch, output_reg);
- __ ucomisd(xmm_scratch, input_reg);
- __ j(equal, &done);
- __ sub(output_reg, Immediate(1));
- // No overflow because we already ruled out minint.
- __ jmp(&done);
-
- __ bind(&round_to_zero);
- // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
- // we can ignore the difference between a result of -0 and +0.
- if (minus_zero_check) {
- // If the sign is positive, we return +0.
- __ movmskpd(output_reg, input_reg);
- __ test(output_reg, Immediate(1));
- __ RecordComment("Minus zero");
- DeoptimizeIf(not_zero, instr->environment());
- }
- __ Set(output_reg, Immediate(0));
- __ bind(&done);
+ __ bind(&round_to_zero);
+ // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
+ // we can ignore the difference between a result of -0 and +0.
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ // If the sign is positive, we return +0.
+ __ movmskpd(output_reg, input_reg);
+ __ test(output_reg, Immediate(1));
+ __ RecordComment("Minus zero");
+ DeoptimizeIf(not_zero, instr->environment());
}
+ __ Set(output_reg, Immediate(0));
+ __ bind(&done);
}
@@ -4035,9 +4022,6 @@
case kMathFloor:
DoMathFloor(instr);
break;
- case kMathRound:
- DoMathRound(instr);
- break;
case kMathSqrt:
DoMathSqrt(instr);
break;
@@ -4146,12 +4130,32 @@
ASSERT(ToRegister(instr->constructor()).is(edi));
ASSERT(ToRegister(instr->result()).is(eax));
+ if (FLAG_optimize_constructed_arrays) {
+ // No cell in ebx for construct type feedback in optimized code
+ Handle<Object> undefined_value(isolate()->heap()->undefined_value(),
+ isolate());
+ __ mov(ebx, Immediate(undefined_value));
+ }
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
__ Set(eax, Immediate(instr->arity()));
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
}
+void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
+ ASSERT(ToRegister(instr->context()).is(esi));
+ ASSERT(ToRegister(instr->constructor()).is(edi));
+ 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);
+}
+
+
void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
CallRuntime(instr->function(), instr->arity(), instr);
}
@@ -5920,13 +5924,13 @@
Register input,
Handle<String> type_name) {
Condition final_branch_condition = no_condition;
- if (type_name->Equals(heap()->number_symbol())) {
+ if (type_name->Equals(heap()->number_string())) {
__ JumpIfSmi(input, true_label);
__ cmp(FieldOperand(input, HeapObject::kMapOffset),
factory()->heap_number_map());
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->string_symbol())) {
+ } else if (type_name->Equals(heap()->string_string())) {
__ JumpIfSmi(input, false_label);
__ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
__ j(above_equal, false_label);
@@ -5934,17 +5938,17 @@
1 << Map::kIsUndetectable);
final_branch_condition = zero;
- } else if (type_name->Equals(heap()->boolean_symbol())) {
+ } else if (type_name->Equals(heap()->boolean_string())) {
__ cmp(input, factory()->true_value());
__ j(equal, true_label);
__ cmp(input, factory()->false_value());
final_branch_condition = equal;
- } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) {
+ } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) {
__ cmp(input, factory()->null_value());
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->undefined_symbol())) {
+ } else if (type_name->Equals(heap()->undefined_string())) {
__ cmp(input, factory()->undefined_value());
__ j(equal, true_label);
__ JumpIfSmi(input, false_label);
@@ -5954,7 +5958,7 @@
1 << Map::kIsUndetectable);
final_branch_condition = not_zero;
- } else if (type_name->Equals(heap()->function_symbol())) {
+ } else if (type_name->Equals(heap()->function_string())) {
STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
__ JumpIfSmi(input, false_label);
__ CmpObjectType(input, JS_FUNCTION_TYPE, input);
@@ -5962,13 +5966,19 @@
__ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE);
final_branch_condition = equal;
- } else if (type_name->Equals(heap()->object_symbol())) {
+ } else if (type_name->Equals(heap()->object_string())) {
__ JumpIfSmi(input, false_label);
if (!FLAG_harmony_typeof) {
__ cmp(input, factory()->null_value());
__ j(equal, true_label);
}
- __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
+ if (FLAG_harmony_symbols) {
+ __ CmpObjectType(input, SYMBOL_TYPE, input);
+ __ j(equal, true_label);
+ __ CmpInstanceType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ } else {
+ __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
+ }
__ j(below, false_label);
__ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ j(above, false_label);