Revision: 11894
Author: [email protected]
Date: Thu Jun 21 04:16:20 2012
Log: Version 3.12.1
Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=11894
Added:
/trunk/test/mjsunit/math-floor-of-div-minus-zero.js
Modified:
/trunk/ChangeLog
/trunk/src/arm/lithium-codegen-arm.cc
/trunk/src/hydrogen-instructions.cc
/trunk/src/hydrogen-instructions.h
/trunk/src/ia32/disasm-ia32.cc
/trunk/src/ia32/lithium-codegen-ia32.cc
/trunk/src/ia32/lithium-ia32.cc
/trunk/src/ia32/lithium-ia32.h
/trunk/src/isolate.cc
/trunk/src/mips/lithium-codegen-mips.cc
/trunk/src/parser.cc
/trunk/src/version.cc
/trunk/src/x64/disasm-x64.cc
/trunk/src/x64/lithium-codegen-x64.cc
/trunk/src/x64/lithium-x64.cc
/trunk/src/x64/lithium-x64.h
/trunk/test/cctest/test-api.cc
/trunk/test/mjsunit/mjsunit.status
/trunk/test/mjsunit/regress/regress-2185-2.js
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/math-floor-of-div-minus-zero.js Thu Jun 21 04:16:20
2012
@@ -0,0 +1,40 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --nouse_inlining
+
+// Test for negative zero that doesn't need bail out
+
+function test_div_no_deopt_minus_zero() {
+ var zero_in_array = [0];
+ assertTrue(0 === (Math.floor((zero_in_array[0] | 0) / -1) | 0));
+}
+
+test_div_no_deopt_minus_zero();
+%OptimizeFunctionOnNextCall(test_div_no_deopt_minus_zero);
+test_div_no_deopt_minus_zero();
+assertTrue(2 != %GetOptimizationStatus(test_div_no_deopt_minus_zero));
=======================================
--- /trunk/ChangeLog Wed Jun 20 04:29:00 2012
+++ /trunk/ChangeLog Thu Jun 21 04:16:20 2012
@@ -1,3 +1,8 @@
+2012-06-21: Version 3.12.1
+
+ Performance and stability improvements on all platforms.
+
+
2012-06-20: Version 3.12.0
Fixed Chromium issues:
=======================================
--- /trunk/src/arm/lithium-codegen-arm.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/arm/lithium-codegen-arm.cc Thu Jun 21 04:16:20 2012
@@ -2597,15 +2597,15 @@
} else {
// Negative lookup.
// Check prototypes.
- HeapObject* current = HeapObject::cast((*type)->prototype());
+ Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
Heap* heap = type->GetHeap();
- while (current != heap->null_value()) {
- Handle<HeapObject> link(current);
- __ LoadHeapObject(result, link);
+ while (*current != heap->null_value()) {
+ __ LoadHeapObject(result, current);
__ ldr(result, FieldMemOperand(result, HeapObject::kMapOffset));
- __ cmp(result, Operand(Handle<Map>(JSObject::cast(current)->map())));
+ __ cmp(result, Operand(Handle<Map>(current->map())));
DeoptimizeIf(ne, env);
- current = HeapObject::cast(current->map()->prototype());
+ current =
+
Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
}
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
}
=======================================
--- /trunk/src/hydrogen-instructions.cc Wed Jun 13 04:51:58 2012
+++ /trunk/src/hydrogen-instructions.cc Thu Jun 21 04:16:20 2012
@@ -941,7 +941,8 @@
// introduced.
if (value()->representation().IsInteger32()) return value();
-#ifdef V8_TARGET_ARCH_ARM
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
+ defined(V8_TARGET_ARCH_X64)
if (value()->IsDiv() && (value()->UseCount() == 1)) {
// TODO(2038): Implement this optimization for non ARM architectures.
HDiv* hdiv = HDiv::cast(value());
@@ -2221,6 +2222,13 @@
}
return NULL;
}
+
+
+HValue* HMathFloorOfDiv::EnsureAndPropagateNotMinusZero(BitVector*
visited) {
+ visited->Add(id());
+ SetFlag(kBailoutOnMinusZero);
+ return NULL;
+}
HValue* HMul::EnsureAndPropagateNotMinusZero(BitVector* visited) {
=======================================
--- /trunk/src/hydrogen-instructions.h Wed Jun 20 04:29:00 2012
+++ /trunk/src/hydrogen-instructions.h Thu Jun 21 04:16:20 2012
@@ -2774,7 +2774,10 @@
: HBinaryOperation(context, left, right) {
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
- }
+ SetFlag(kCanOverflow);
+ }
+
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Integer32();
=======================================
--- /trunk/src/ia32/disasm-ia32.cc Tue Dec 13 00:07:27 2011
+++ /trunk/src/ia32/disasm-ia32.cc Thu Jun 21 04:16:20 2012
@@ -553,6 +553,7 @@
case 2: mnem = "not"; break;
case 3: mnem = "neg"; break;
case 4: mnem = "mul"; break;
+ case 5: mnem = "imul"; break;
case 7: mnem = "idiv"; break;
default: UnimplementedInstruction();
}
=======================================
--- /trunk/src/ia32/lithium-codegen-ia32.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/ia32/lithium-codegen-ia32.cc Thu Jun 21 04:16:20 2012
@@ -1020,6 +1020,109 @@
__ test(edx, Operand(edx));
DeoptimizeIf(not_zero, instr->environment());
}
+
+
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+ ASSERT(instr->InputAt(1)->IsConstantOperand());
+
+ Register dividend = ToRegister(instr->InputAt(0));
+ int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
+ Register result = ToRegister(instr->result());
+
+ switch (divisor) {
+ case 0:
+ DeoptimizeIf(no_condition, instr->environment());
+ return;
+
+ case 1:
+ __ Move(result, dividend);
+ return;
+
+ case -1:
+ __ Move(result, dividend);
+ __ neg(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+ return;
+ }
+
+ uint32_t divisor_abs = abs(divisor);
+ if (IsPowerOf2(divisor_abs)) {
+ int32_t power = WhichPowerOf2(divisor_abs);
+ if (divisor < 0) {
+ // Input[dividend] is clobbered.
+ // The sequence is tedious because neg(dividend) might overflow.
+ __ mov(result, dividend);
+ __ sar(dividend, 31);
+ __ neg(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ shl(dividend, 32 - power);
+ __ sar(result, power);
+ __ not_(dividend);
+ // Clear result.sign if dividend.sign is set.
+ __ and_(result, dividend);
+ } else {
+ __ Move(result, dividend);
+ __ sar(result, power);
+ }
+ } else {
+ ASSERT(ToRegister(instr->InputAt(0)).is(eax));
+ ASSERT(ToRegister(instr->result()).is(edx));
+ Register scratch = ToRegister(instr->TempAt(0));
+
+ // Find b which: 2^b < divisor_abs < 2^(b+1).
+ unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
+ unsigned shift = 32 + b; // Precision +1bit (effectively).
+ double multiplier_f =
+ static_cast<double>(static_cast<uint64_t>(1) << shift) /
divisor_abs;
+ int64_t multiplier;
+ if (multiplier_f - floor(multiplier_f) < 0.5) {
+ multiplier = static_cast<int64_t>(floor(multiplier_f));
+ } else {
+ multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1;
+ }
+ // The multiplier is a uint32.
+ ASSERT(multiplier > 0 &&
+ multiplier < (static_cast<int64_t>(1) << 32));
+ __ mov(scratch, dividend);
+ if (divisor < 0 &&
+ instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ test(dividend, dividend);
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ mov(edx, static_cast<int32_t>(multiplier));
+ __ imul(edx);
+ if (static_cast<int32_t>(multiplier) < 0) {
+ __ add(edx, scratch);
+ }
+ Register reg_lo = eax;
+ Register reg_byte_scratch = scratch;
+ if (!reg_byte_scratch.is_byte_register()) {
+ __ xchg(reg_lo, reg_byte_scratch);
+ reg_lo = scratch;
+ reg_byte_scratch = eax;
+ }
+ if (divisor < 0) {
+ __ xor_(reg_byte_scratch, reg_byte_scratch);
+ __ cmp(reg_lo, 0x40000000);
+ __ setcc(above, reg_byte_scratch);
+ __ neg(edx);
+ __ sub(edx, reg_byte_scratch);
+ } else {
+ __ xor_(reg_byte_scratch, reg_byte_scratch);
+ __ cmp(reg_lo, 0xC0000000);
+ __ setcc(above_equal, reg_byte_scratch);
+ __ add(edx, reg_byte_scratch);
+ }
+ __ sar(edx, shift - 32);
+ }
+}
void LCodeGen::DoMulI(LMulI* instr) {
@@ -2327,15 +2430,15 @@
} else {
// Negative lookup.
// Check prototypes.
- HeapObject* current = HeapObject::cast((*type)->prototype());
+ Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
Heap* heap = type->GetHeap();
- while (current != heap->null_value()) {
- Handle<HeapObject> link(current);
- __ LoadHeapObject(result, link);
+ while (*current != heap->null_value()) {
+ __ LoadHeapObject(result, current);
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
- Handle<Map>(JSObject::cast(current)->map()));
+ Handle<Map>(current->map()));
DeoptimizeIf(not_equal, env);
- current = HeapObject::cast(current->map()->prototype());
+ current =
+
Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
}
__ mov(result, factory()->undefined_value());
}
=======================================
--- /trunk/src/ia32/lithium-ia32.cc Wed Jun 13 04:51:58 2012
+++ /trunk/src/ia32/lithium-ia32.cc Thu Jun 21 04:16:20 2012
@@ -1347,10 +1347,55 @@
}
-LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
- UNIMPLEMENTED();
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue*
dividend) {
+ // A value with an integer representation does not need to be
transformed.
+ if (dividend->representation().IsInteger32()) {
+ return dividend;
+ // A change from an integer32 can be replaced by the integer32 value.
+ } else if (dividend->IsChange() &&
+ HChange::cast(dividend)->from().IsInteger32()) {
+ return HChange::cast(dividend)->value();
+ }
return NULL;
}
+
+
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor)
{
+ if (divisor->IsConstant() &&
+ HConstant::cast(divisor)->HasInteger32Value()) {
+ HConstant* constant_val = HConstant::cast(divisor);
+ return constant_val->CopyToRepresentation(Representation::Integer32(),
+ divisor->block()->zone());
+ }
+ return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
+ HValue* right = instr->right();
+ ASSERT(right->IsConstant() &&
HConstant::cast(right)->HasInteger32Value());
+ LOperand* divisor =
chunk_->DefineConstantOperand(HConstant::cast(right));
+ int32_t divisor_si = HConstant::cast(right)->Integer32Value();
+ if (divisor_si == 0) {
+ LOperand* dividend = UseRegister(instr->left());
+ return AssignEnvironment(DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL)));
+ } else if (IsPowerOf2(abs(divisor_si))) {
+ // use dividend as temp if divisor < 0 && divisor != -1
+ LOperand* dividend = divisor_si < -1 ? UseTempRegister(instr->left()) :
+ UseRegisterAtStart(instr->left());
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL));
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ } else {
+ // needs edx:eax, plus a temp
+ LOperand* dividend = UseFixed(instr->left(), eax);
+ LOperand* temp = TempRegister();
+ LInstruction* result = DefineFixed(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx);
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ }
+}
LInstruction* LChunkBuilder::DoMod(HMod* instr) {
=======================================
--- /trunk/src/ia32/lithium-ia32.h Wed Jun 13 04:51:58 2012
+++ /trunk/src/ia32/lithium-ia32.h Thu Jun 21 04:16:20 2012
@@ -126,6 +126,7 @@
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MathFloorOfDiv) \
V(MathPowHalf) \
V(ModI) \
V(MulI) \
@@ -546,6 +547,21 @@
};
+class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
+ public:
+ LMathFloorOfDiv(LOperand* left,
+ LOperand* right,
+ LOperand* temp = NULL) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ temps_[0] = temp;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI: public LTemplateInstruction<1, 2, 1> {
public:
LMulI(LOperand* left, LOperand* right, LOperand* temp) {
@@ -2399,6 +2415,9 @@
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
+ static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val);
+ static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
+
private:
enum Status {
UNUSED,
=======================================
--- /trunk/src/isolate.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/isolate.cc Thu Jun 21 04:16:20 2012
@@ -945,12 +945,9 @@
// When scheduling a throw we first throw the exception to get the
// error reporting if it is uncaught before rescheduling it.
Throw(exception);
- PropagatePendingExceptionToExternalTryCatch();
- if (has_pending_exception()) {
- thread_local_top()->scheduled_exception_ = pending_exception();
- thread_local_top()->external_caught_exception_ = false;
- clear_pending_exception();
- }
+ thread_local_top()->scheduled_exception_ = pending_exception();
+ thread_local_top()->external_caught_exception_ = false;
+ clear_pending_exception();
}
=======================================
--- /trunk/src/mips/lithium-codegen-mips.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/mips/lithium-codegen-mips.cc Thu Jun 21 04:16:20 2012
@@ -2341,15 +2341,14 @@
} else {
// Negative lookup.
// Check prototypes.
- HeapObject* current = HeapObject::cast((*type)->prototype());
+ Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
Heap* heap = type->GetHeap();
- while (current != heap->null_value()) {
- Handle<HeapObject> link(current);
- __ LoadHeapObject(result, link);
+ while (*current != heap->null_value()) {
+ __ LoadHeapObject(result, current);
__ lw(result, FieldMemOperand(result, HeapObject::kMapOffset));
- DeoptimizeIf(ne, env,
- result, Operand(Handle<Map>(JSObject::cast(current)->map())));
- current = HeapObject::cast(current->map()->prototype());
+ DeoptimizeIf(ne, env, result, Operand(Handle<Map>(current->map())));
+ current =
+
Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
}
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
}
=======================================
--- /trunk/src/parser.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/parser.cc Thu Jun 21 04:16:20 2012
@@ -6026,7 +6026,6 @@
bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
ASSERT(info->function() == NULL);
FunctionLiteral* result = NULL;
- Handle<Script> script = info->script();
ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
if (!info->is_native() && FLAG_harmony_scoping) {
// Harmony scoping is requested.
=======================================
--- /trunk/src/version.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/version.cc Thu Jun 21 04:16:20 2012
@@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 12
-#define BUILD_NUMBER 0
+#define BUILD_NUMBER 1
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x64/disasm-x64.cc Tue May 22 02:16:05 2012
+++ /trunk/src/x64/disasm-x64.cc Thu Jun 21 04:16:20 2012
@@ -703,6 +703,9 @@
case 4:
mnem = "mul";
break;
+ case 5:
+ mnem = "imul";
+ break;
case 7:
mnem = "idiv";
break;
=======================================
--- /trunk/src/x64/lithium-codegen-x64.cc Wed Jun 20 04:29:00 2012
+++ /trunk/src/x64/lithium-codegen-x64.cc Thu Jun 21 04:16:20 2012
@@ -884,6 +884,89 @@
__ bind(&done);
}
}
+
+
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+ ASSERT(instr->InputAt(1)->IsConstantOperand());
+
+ const Register dividend = ToRegister(instr->InputAt(0));
+ int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
+ const Register result = ToRegister(instr->result());
+
+ switch (divisor) {
+ case 0:
+ DeoptimizeIf(no_condition, instr->environment());
+ return;
+
+ case 1:
+ if (!result.is(dividend)) {
+ __ movl(result, dividend);
+ }
+ return;
+
+ case -1:
+ if (!result.is(dividend)) {
+ __ movl(result, dividend);
+ }
+ __ negl(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+ return;
+ }
+
+ uint32_t divisor_abs = abs(divisor);
+ if (IsPowerOf2(divisor_abs)) {
+ int32_t power = WhichPowerOf2(divisor_abs);
+ if (divisor < 0) {
+ __ movsxlq(result, dividend);
+ __ neg(result);
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ sar(result, Immediate(power));
+ } else {
+ if (!result.is(dividend)) {
+ __ movl(result, dividend);
+ }
+ __ sarl(result, Immediate(power));
+ }
+ } else {
+ Register reg1 = ToRegister(instr->TempAt(0));
+ Register reg2 = ToRegister(instr->result());
+
+ // Find b which: 2^b < divisor_abs < 2^(b+1).
+ unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
+ unsigned shift = 32 + b; // Precision +1bit (effectively).
+ double multiplier_f =
+ static_cast<double>(static_cast<uint64_t>(1) << shift) /
divisor_abs;
+ int64_t multiplier;
+ if (multiplier_f - floor(multiplier_f) < 0.5) {
+ multiplier = static_cast<int64_t>(floor(multiplier_f));
+ } else {
+ multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1;
+ }
+ // The multiplier is a uint32.
+ ASSERT(multiplier > 0 &&
+ multiplier < (static_cast<int64_t>(1) << 32));
+ // The multiply is int64, so sign-extend to r64.
+ __ movsxlq(reg1, dividend);
+ if (divisor < 0 &&
+ instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ neg(reg1);
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ movq(reg2, multiplier, RelocInfo::NONE);
+ // Result just fit in r64, because it's int32 * uint32.
+ __ imul(reg2, reg1);
+
+ __ addq(reg2, Immediate(1 << 30));
+ __ sar(reg2, Immediate(shift));
+ }
+}
void LCodeGen::DoDivI(LDivI* instr) {
@@ -2221,15 +2304,15 @@
} else {
// Negative lookup.
// Check prototypes.
- HeapObject* current = HeapObject::cast((*type)->prototype());
+ Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
Heap* heap = type->GetHeap();
- while (current != heap->null_value()) {
- Handle<HeapObject> link(current);
- __ LoadHeapObject(result, link);
+ while (*current != heap->null_value()) {
+ __ LoadHeapObject(result, current);
__ Cmp(FieldOperand(result, HeapObject::kMapOffset),
- Handle<Map>(JSObject::cast(current)->map()));
+ Handle<Map>(current->map()));
DeoptimizeIf(not_equal, env);
- current = HeapObject::cast(current->map()->prototype());
+ current =
+
Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
}
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
}
=======================================
--- /trunk/src/x64/lithium-x64.cc Wed Jun 13 04:51:58 2012
+++ /trunk/src/x64/lithium-x64.cc Thu Jun 21 04:16:20 2012
@@ -1287,10 +1287,53 @@
}
-LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
- UNIMPLEMENTED();
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue*
dividend) {
+ // A value with an integer representation does not need to be
transformed.
+ if (dividend->representation().IsInteger32()) {
+ return dividend;
+ // A change from an integer32 can be replaced by the integer32 value.
+ } else if (dividend->IsChange() &&
+ HChange::cast(dividend)->from().IsInteger32()) {
+ return HChange::cast(dividend)->value();
+ }
return NULL;
}
+
+
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor)
{
+ if (divisor->IsConstant() &&
+ HConstant::cast(divisor)->HasInteger32Value()) {
+ HConstant* constant_val = HConstant::cast(divisor);
+ return constant_val->CopyToRepresentation(Representation::Integer32(),
+ divisor->block()->zone());
+ }
+ return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
+ HValue* right = instr->right();
+ ASSERT(right->IsConstant() &&
HConstant::cast(right)->HasInteger32Value());
+ LOperand* divisor =
chunk_->DefineConstantOperand(HConstant::cast(right));
+ int32_t divisor_si = HConstant::cast(right)->Integer32Value();
+ if (divisor_si == 0) {
+ LOperand* dividend = UseRegister(instr->left());
+ return AssignEnvironment(DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL)));
+ } else if (IsPowerOf2(abs(divisor_si))) {
+ LOperand* dividend = UseRegisterAtStart(instr->left());
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL));
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ } else {
+ // use two r64
+ LOperand* dividend = UseRegisterAtStart(instr->left());
+ LOperand* temp = TempRegister();
+ LInstruction* result = DefineAsRegister(
+ new(zone()) LMathFloorOfDiv(dividend, divisor, temp));
+ return divisor_si < 0 ? AssignEnvironment(result) : result;
+ }
+}
LInstruction* LChunkBuilder::DoMod(HMod* instr) {
=======================================
--- /trunk/src/x64/lithium-x64.h Wed Jun 13 04:51:58 2012
+++ /trunk/src/x64/lithium-x64.h Thu Jun 21 04:16:20 2012
@@ -132,6 +132,7 @@
V(LoadNamedField) \
V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
+ V(MathFloorOfDiv) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -554,6 +555,21 @@
};
+class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
+ public:
+ LMathFloorOfDiv(LOperand* left,
+ LOperand* right,
+ LOperand* temp = NULL) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ temps_[0] = temp;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div")
+ DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
class LMulI: public LTemplateInstruction<1, 2, 0> {
public:
LMulI(LOperand* left, LOperand* right) {
@@ -2255,6 +2271,9 @@
HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
#undef DECLARE_DO
+ static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val);
+ static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
+
private:
enum Status {
UNUSED,
=======================================
--- /trunk/test/cctest/test-api.cc Wed Jun 20 04:29:00 2012
+++ /trunk/test/cctest/test-api.cc Thu Jun 21 04:16:20 2012
@@ -3361,30 +3361,6 @@
"}\n");
CHECK(try_catch.HasCaught());
}
-
-
-static void TryCatchNestedHelper(int depth) {
- if (depth > 0) {
- v8::TryCatch try_catch;
- try_catch.SetVerbose(true);
- TryCatchNestedHelper(depth - 1);
- CHECK(try_catch.HasCaught());
- try_catch.ReThrow();
- } else {
- v8::ThrowException(v8_str("back"));
- }
-}
-
-
-TEST(TryCatchNested) {
- v8::V8::Initialize();
- v8::HandleScope scope;
- LocalContext context;
- v8::TryCatch try_catch;
- TryCatchNestedHelper(5);
- CHECK(try_catch.HasCaught());
- CHECK_EQ(0,
strcmp(*v8::String::Utf8Value(try_catch.Exception()), "back"));
-}
THREADED_TEST(Equality) {
@@ -5242,7 +5218,7 @@
object.MarkIndependent();
HEAP->PerformScavenge();
CHECK(revived);
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
{
v8::HandleScope handle_scope;
v8::Local<String> y_str = v8_str("y");
@@ -9394,7 +9370,8 @@
v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) {
static int count = 0;
if (count++ % 3 == 0) {
- HEAP-> CollectAllGarbage(true); // This should move the stub
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+ // This should move the stub
GenerateSomeGarbage(); // This should ensure the old stub memory is
flushed
}
return v8::Handle<v8::Value>();
@@ -9449,7 +9426,7 @@
v8::Handle<v8::Value> DirectGetterCallback(Local<String> name,
const v8::AccessorInfo& info) {
if (++p_getter_count % 3 == 0) {
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
GenerateSomeGarbage();
}
return v8::Handle<v8::Value>();
@@ -16120,7 +16097,8 @@
CHECK_LE(1, elements);
}
- i::Isolate::Current()->heap()->CollectAllGarbage(true);
+ i::Isolate::Current()->heap()->CollectAllGarbage(
+ i::Heap::kAbortIncrementalMarkingMask);
{ i::Object* raw_map_cache =
i::Isolate::Current()->context()->map_cache();
if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value())
{
i::MapCache* map_cache = i::MapCache::cast(raw_map_cache);
=======================================
--- /trunk/test/mjsunit/mjsunit.status Wed Jun 20 04:29:00 2012
+++ /trunk/test/mjsunit/mjsunit.status Thu Jun 21 04:16:20 2012
@@ -126,6 +126,9 @@
debug-liveedit-stack-padding: SKIP
debug-liveedit-restart-frame: SKIP
+# Currently always deopt on minus zero
+math-floor-of-div-minus-zero: SKIP
+
##############################################################################
[ $arch == mips ]
=======================================
--- /trunk/test/mjsunit/regress/regress-2185-2.js Wed Jun 20 04:29:00 2012
+++ /trunk/test/mjsunit/regress/regress-2185-2.js Thu Jun 21 04:16:20 2012
@@ -27,7 +27,7 @@
// These tests used to time out before this was fixed.
-var LEN = 1e5;
+var LEN = 3e4;
function short() {
var sum = 0;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev