diff options
Diffstat (limited to 'src/3rdparty/v8/src/mips/ic-mips.cc')
-rw-r--r-- | src/3rdparty/v8/src/mips/ic-mips.cc | 275 |
1 files changed, 155 insertions, 120 deletions
diff --git a/src/3rdparty/v8/src/mips/ic-mips.cc b/src/3rdparty/v8/src/mips/ic-mips.cc index 964a7e2..cf70681 100644 --- a/src/3rdparty/v8/src/mips/ic-mips.cc +++ b/src/3rdparty/v8/src/mips/ic-mips.cc @@ -398,7 +398,7 @@ void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, Code::Flags flags = Code::ComputeFlags(kind, MONOMORPHIC, extra_state, - NORMAL, + Code::NORMAL, argc); Isolate::Current()->stub_cache()->GenerateProbe( masm, flags, a1, a2, a3, t0, t1, t2); @@ -1189,6 +1189,145 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, } +static void KeyedStoreGenerateGenericHelper( + MacroAssembler* masm, + Label* fast_object, + Label* fast_double, + Label* slow, + KeyedStoreCheckMap check_map, + KeyedStoreIncrementLength increment_length, + Register value, + Register key, + Register receiver, + Register receiver_map, + Register elements_map, + Register elements) { + Label transition_smi_elements; + Label finish_object_store, non_double_value, transition_double_elements; + Label fast_double_without_map_check; + + // Fast case: Do the store, could be either Object or double. + __ bind(fast_object); + Register scratch_value = t0; + Register address = t1; + if (check_map == kCheckMap) { + __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); + __ Branch(fast_double, ne, elements_map, + Operand(masm->isolate()->factory()->fixed_array_map())); + } + // Smi stores don't require further checks. + Label non_smi_value; + __ JumpIfNotSmi(value, &non_smi_value); + + if (increment_length == kIncrementLength) { + // Add 1 to receiver->length. + __ Addu(scratch_value, key, Operand(Smi::FromInt(1))); + __ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); + } + // It's irrelevant whether array is smi-only or not when writing a smi. + __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); + __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize); + __ Addu(address, address, scratch_value); + __ sw(value, MemOperand(address)); + __ Ret(); + + __ bind(&non_smi_value); + // Escape to elements kind transition case. + __ CheckFastObjectElements(receiver_map, scratch_value, + &transition_smi_elements); + + // Fast elements array, store the value to the elements backing store. + __ bind(&finish_object_store); + if (increment_length == kIncrementLength) { + // Add 1 to receiver->length. + __ Addu(scratch_value, key, Operand(Smi::FromInt(1))); + __ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); + } + __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); + __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize); + __ Addu(address, address, scratch_value); + __ sw(value, MemOperand(address)); + // Update write barrier for the elements array address. + __ mov(scratch_value, value); // Preserve the value which is returned. + __ RecordWrite(elements, + address, + scratch_value, + kRAHasNotBeenSaved, + kDontSaveFPRegs, + EMIT_REMEMBERED_SET, + OMIT_SMI_CHECK); + __ Ret(); + + __ bind(fast_double); + if (check_map == kCheckMap) { + // Check for fast double array case. If this fails, call through to the + // runtime. + __ LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex); + __ Branch(slow, ne, elements_map, Operand(at)); + } + __ bind(&fast_double_without_map_check); + __ StoreNumberToDoubleElements(value, + key, + receiver, + elements, // Overwritten. + a3, // Scratch regs... + t0, + t1, + t2, + &transition_double_elements); + if (increment_length == kIncrementLength) { + // Add 1 to receiver->length. + __ Addu(scratch_value, key, Operand(Smi::FromInt(1))); + __ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); + } + __ Ret(); + + __ bind(&transition_smi_elements); + // Transition the array appropriately depending on the value type. + __ lw(t0, FieldMemOperand(value, HeapObject::kMapOffset)); + __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); + __ Branch(&non_double_value, ne, t0, Operand(at)); + + // Value is a double. Transition FAST_SMI_ELEMENTS -> + // FAST_DOUBLE_ELEMENTS and complete the store. + __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, + FAST_DOUBLE_ELEMENTS, + receiver_map, + t0, + slow); + ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 + ElementsTransitionGenerator::GenerateSmiToDouble(masm, slow); + __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); + __ jmp(&fast_double_without_map_check); + + __ bind(&non_double_value); + // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS + __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, + FAST_ELEMENTS, + receiver_map, + t0, + slow); + ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 + ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm); + __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); + __ jmp(&finish_object_store); + + __ bind(&transition_double_elements); + // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a + // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and + // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS + __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, + FAST_ELEMENTS, + receiver_map, + t0, + slow); + ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 + ElementsTransitionGenerator::GenerateDoubleToObject(masm, slow); + __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); + __ jmp(&finish_object_store); +} + + void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode) { // ---------- S t a t e -------------- @@ -1197,11 +1336,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, // -- a2 : receiver // -- ra : return address // ----------------------------------- - Label slow, array, extra, check_if_double_array; - Label fast_object_with_map_check, fast_object_without_map_check; - Label fast_double_with_map_check, fast_double_without_map_check; - Label transition_smi_elements, finish_object_store, non_double_value; - Label transition_double_elements; + Label slow, fast_object, fast_object_grow; + Label fast_double, fast_double_grow; + Label array, extra, check_if_double_array; // Register usage. Register value = a0; @@ -1233,7 +1370,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); // Check array bounds. Both the key and the length of FixedArray are smis. __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); - __ Branch(&fast_object_with_map_check, lo, key, Operand(t0)); + __ Branch(&fast_object, lo, key, Operand(t0)); // Slow case, handle jump to runtime. __ bind(&slow); @@ -1258,19 +1395,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, __ Branch( &check_if_double_array, ne, elements_map, Heap::kFixedArrayMapRootIndex); - // Calculate key + 1 as smi. - STATIC_ASSERT(kSmiTag == 0); - __ Addu(t0, key, Operand(Smi::FromInt(1))); - __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); - __ Branch(&fast_object_without_map_check); + __ jmp(&fast_object_grow); __ bind(&check_if_double_array); __ Branch(&slow, ne, elements_map, Heap::kFixedDoubleArrayMapRootIndex); - // Add 1 to key, and go to common element store code for doubles. - STATIC_ASSERT(kSmiTag == 0); - __ Addu(t0, key, Operand(Smi::FromInt(1))); - __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); - __ jmp(&fast_double_without_map_check); + __ jmp(&fast_double_grow); // Array case: Get the length and the elements array from the JS // array. Check that the array is in fast mode (and writable); if it @@ -1281,109 +1410,15 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, // Check the key against the length in the array. __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); __ Branch(&extra, hs, key, Operand(t0)); - // Fall through to fast case. - - __ bind(&fast_object_with_map_check); - Register scratch_value = t0; - Register address = t1; - __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); - __ Branch(&fast_double_with_map_check, - ne, - elements_map, - Heap::kFixedArrayMapRootIndex); - __ bind(&fast_object_without_map_check); - // Smi stores don't require further checks. - Label non_smi_value; - __ JumpIfNotSmi(value, &non_smi_value); - // It's irrelevant whether array is smi-only or not when writing a smi. - __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize); - __ Addu(address, address, scratch_value); - __ sw(value, MemOperand(address)); - __ Ret(USE_DELAY_SLOT); - __ mov(v0, value); - - __ bind(&non_smi_value); - // Escape to elements kind transition case. - __ CheckFastObjectElements(receiver_map, scratch_value, - &transition_smi_elements); - // Fast elements array, store the value to the elements backing store. - __ bind(&finish_object_store); - __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize); - __ Addu(address, address, scratch_value); - __ sw(value, MemOperand(address)); - // Update write barrier for the elements array address. - __ mov(v0, value); // Preserve the value which is returned. - __ RecordWrite(elements, - address, - value, - kRAHasNotBeenSaved, - kDontSaveFPRegs, - EMIT_REMEMBERED_SET, - OMIT_SMI_CHECK); - __ Ret(); - - __ bind(&fast_double_with_map_check); - // Check for fast double array case. If this fails, call through to the - // runtime. - __ Branch(&slow, ne, elements_map, Heap::kFixedDoubleArrayMapRootIndex); - __ bind(&fast_double_without_map_check); - __ StoreNumberToDoubleElements(value, - key, - receiver, - elements, - a3, - t0, - t1, - t2, - &transition_double_elements); - __ Ret(USE_DELAY_SLOT); - __ mov(v0, value); - - __ bind(&transition_smi_elements); - // Transition the array appropriately depending on the value type. - __ lw(t0, FieldMemOperand(value, HeapObject::kMapOffset)); - __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); - __ Branch(&non_double_value, ne, t0, Operand(at)); - - // Value is a double. Transition FAST_SMI_ONLY_ELEMENTS -> - // FAST_DOUBLE_ELEMENTS and complete the store. - __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, - FAST_DOUBLE_ELEMENTS, - receiver_map, - t0, - &slow); - ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 - ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &slow); - __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ jmp(&fast_double_without_map_check); - - __ bind(&non_double_value); - // Value is not a double, FAST_SMI_ONLY_ELEMENTS -> FAST_ELEMENTS - __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, - FAST_ELEMENTS, - receiver_map, - t0, - &slow); - ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 - ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm); - __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ jmp(&finish_object_store); - __ bind(&transition_double_elements); - // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a - // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and - // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS - __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, - FAST_ELEMENTS, - receiver_map, - t0, - &slow); - ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 - ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow); - __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ jmp(&finish_object_store); + KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, + &slow, kCheckMap, kDontIncrementLength, + value, key, receiver, receiver_map, + elements_map, elements); + KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, + &slow, kDontCheckMap, kIncrementLength, + value, key, receiver, receiver_map, + elements_map, elements); } @@ -1471,7 +1506,7 @@ void KeyedStoreIC::GenerateTransitionElementsSmiToDouble(MacroAssembler* masm) { // Must return the modified receiver in v0. if (!FLAG_trace_elements_transitions) { Label fail; - ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &fail); + ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail); __ Ret(USE_DELAY_SLOT); __ mov(v0, a2); __ bind(&fail); |