| Index: src/arm/lithium-codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/lithium-codegen-arm.cc (revision 8778)
|
| +++ src/arm/lithium-codegen-arm.cc (working copy)
|
| @@ -549,6 +549,13 @@
|
| RecordPosition(pointers->position());
|
| __ Call(code, mode);
|
| RegisterLazyDeoptimization(instr, safepoint_mode);
|
| +
|
| + // Signal that we don't inline smi code before these stubs in the
|
| + // optimizing code generator.
|
| + if (code->kind() == Code::BINARY_OP_IC ||
|
| + code->kind() == Code::COMPARE_IC) {
|
| + __ nop();
|
| + }
|
| }
|
|
|
|
|
| @@ -1504,6 +1511,7 @@
|
|
|
| BinaryOpStub stub(instr->op(), NO_OVERWRITE);
|
| CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
| + __ nop(); // Signals no inlined code.
|
| }
|
|
|
|
|
| @@ -2428,6 +2436,48 @@
|
| }
|
|
|
|
|
| +void LCodeGen::DoLoadKeyedFastDoubleElement(
|
| + LLoadKeyedFastDoubleElement* instr) {
|
| + Register elements = ToRegister(instr->elements());
|
| + bool key_is_constant = instr->key()->IsConstantOperand();
|
| + Register key = no_reg;
|
| + DwVfpRegister result = ToDoubleRegister(instr->result());
|
| + Register scratch = scratch0();
|
| +
|
| + int shift_size =
|
| + ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS);
|
| + int constant_key = 0;
|
| + if (key_is_constant) {
|
| + constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| + if (constant_key & 0xF0000000) {
|
| + Abort("array index constant value too big.");
|
| + }
|
| + } else {
|
| + key = ToRegister(instr->key());
|
| + }
|
| +
|
| + Operand operand = key_is_constant
|
| + ? Operand(constant_key * (1 << shift_size) +
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag)
|
| + : Operand(key, LSL, shift_size);
|
| + __ add(elements, elements, operand);
|
| + if (!key_is_constant) {
|
| + __ add(elements, elements,
|
| + Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + }
|
| +
|
| + if (instr->hydrogen()->RequiresHoleCheck()) {
|
| + // TODO(danno): If no hole check is required, there is no need to allocate
|
| + // elements into a temporary register, instead scratch can be used.
|
| + __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
|
| + __ cmp(scratch, Operand(kHoleNanUpper32));
|
| + DeoptimizeIf(eq, instr->environment());
|
| + }
|
| +
|
| + __ vldr(result, elements, 0);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
| LLoadKeyedSpecializedArrayElement* instr) {
|
| Register external_pointer = ToRegister(instr->external_pointer());
|
| @@ -2448,9 +2498,10 @@
|
| if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
|
| elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - DwVfpRegister result(ToDoubleRegister(instr->result()));
|
| - Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
|
| - : Operand(key, LSL, shift_size));
|
| + DwVfpRegister result = ToDoubleRegister(instr->result());
|
| + Operand operand = key_is_constant
|
| + ? Operand(constant_key * (1 << shift_size))
|
| + : Operand(key, LSL, shift_size);
|
| __ add(scratch0(), external_pointer, operand);
|
| if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
|
| __ vldr(result.low(), scratch0(), 0);
|
| @@ -2459,7 +2510,7 @@
|
| __ vldr(result, scratch0(), 0);
|
| }
|
| } else {
|
| - Register result(ToRegister(instr->result()));
|
| + Register result = ToRegister(instr->result());
|
| MemOperand mem_operand(key_is_constant
|
| ? MemOperand(external_pointer, constant_key * (1 << shift_size))
|
| : MemOperand(external_pointer, key, LSL, shift_size));
|
| @@ -3240,6 +3291,48 @@
|
| }
|
|
|
|
|
| +void LCodeGen::DoStoreKeyedFastDoubleElement(
|
| + LStoreKeyedFastDoubleElement* instr) {
|
| + DwVfpRegister value = ToDoubleRegister(instr->value());
|
| + Register elements = ToRegister(instr->elements());
|
| + Register key = no_reg;
|
| + Register scratch = scratch0();
|
| + bool key_is_constant = instr->key()->IsConstantOperand();
|
| + int constant_key = 0;
|
| + Label not_nan;
|
| +
|
| + // Calculate the effective address of the slot in the array to store the
|
| + // double value.
|
| + if (key_is_constant) {
|
| + constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| + if (constant_key & 0xF0000000) {
|
| + Abort("array index constant value too big.");
|
| + }
|
| + } else {
|
| + key = ToRegister(instr->key());
|
| + }
|
| + int shift_size = ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS);
|
| + Operand operand = key_is_constant
|
| + ? Operand(constant_key * (1 << shift_size) +
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag)
|
| + : Operand(key, LSL, shift_size);
|
| + __ add(scratch, elements, operand);
|
| + if (!key_is_constant) {
|
| + __ add(scratch, scratch,
|
| + Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + }
|
| +
|
| + // Check for NaN. All NaNs must be canonicalized.
|
| + __ VFPCompareAndSetFlags(value, value);
|
| +
|
| + // Only load canonical NaN if the comparison above set the overflow.
|
| + __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs);
|
| +
|
| + __ bind(¬_nan);
|
| + __ vstr(value, scratch, 0);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoStoreKeyedSpecializedArrayElement(
|
| LStoreKeyedSpecializedArrayElement* instr) {
|
|
|
| @@ -3982,7 +4075,7 @@
|
| // conversions.
|
| __ cmp(input_reg, Operand(factory()->undefined_value()));
|
| DeoptimizeIf(ne, instr->environment());
|
| - __ movt(input_reg, 0);
|
| + __ mov(result_reg, Operand(0));
|
| __ jmp(&done);
|
|
|
| // Heap number
|
|
|