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

Side by Side Diff: src/ic/mips/ic-mips.cc

Issue 2523473002: [cleanup] Drop handwritten KeyedStoreIC code (Closed)
Patch Set: rebased Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « src/ic/mips/ic-compiler-mips.cc ('k') | src/ic/mips/stub-cache-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_MIPS 5 #if V8_TARGET_ARCH_MIPS
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/ic-compiler.h" 9 #include "src/ic/ic-compiler.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 193
194 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 194 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
195 // The return address is in ra. 195 // The return address is in ra.
196 196
197 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 197 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
198 198
199 // Do tail-call to runtime routine. 199 // Do tail-call to runtime routine.
200 __ TailCallRuntime(Runtime::kKeyedGetProperty); 200 __ TailCallRuntime(Runtime::kKeyedGetProperty);
201 } 201 }
202 202
203 static void KeyedStoreGenerateMegamorphicHelper(
204 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
205 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
206 Register value, Register key, Register receiver, Register receiver_map,
207 Register elements_map, Register elements) {
208 Label transition_smi_elements;
209 Label finish_object_store, non_double_value, transition_double_elements;
210 Label fast_double_without_map_check;
211
212 // Fast case: Do the store, could be either Object or double.
213 __ bind(fast_object);
214 Register scratch = t0;
215 Register scratch2 = t4;
216 Register scratch3 = t5;
217 Register address = t1;
218 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
219 scratch, scratch2, scratch3, address));
220
221 if (check_map == kCheckMap) {
222 __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
223 __ Branch(fast_double, ne, elements_map,
224 Operand(masm->isolate()->factory()->fixed_array_map()));
225 }
226
227 // HOLECHECK: guards "A[i] = V"
228 // We have to go to the runtime if the current value is the hole because
229 // there may be a callback on the element.
230 Label holecheck_passed1;
231 __ Addu(address, elements, FixedArray::kHeaderSize - kHeapObjectTag);
232 __ Lsa(address, address, key, kPointerSizeLog2 - kSmiTagSize);
233 __ lw(scratch, MemOperand(address));
234 __ Branch(&holecheck_passed1, ne, scratch,
235 Operand(masm->isolate()->factory()->the_hole_value()));
236 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
237
238 __ bind(&holecheck_passed1);
239
240 // Smi stores don't require further checks.
241 Label non_smi_value;
242 __ JumpIfNotSmi(value, &non_smi_value);
243
244 if (increment_length == kIncrementLength) {
245 // Add 1 to receiver->length.
246 __ Addu(scratch, key, Operand(Smi::FromInt(1)));
247 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
248 }
249 // It's irrelevant whether array is smi-only or not when writing a smi.
250 __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
251 __ Lsa(address, address, key, kPointerSizeLog2 - kSmiTagSize);
252 __ sw(value, MemOperand(address));
253 __ Ret(USE_DELAY_SLOT);
254 __ Move(v0, value); // Ensure the stub returns correct value.
255
256 __ bind(&non_smi_value);
257 // Escape to elements kind transition case.
258 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
259
260 // Fast elements array, store the value to the elements backing store.
261 __ bind(&finish_object_store);
262 if (increment_length == kIncrementLength) {
263 // Add 1 to receiver->length.
264 __ Addu(scratch, key, Operand(Smi::FromInt(1)));
265 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
266 }
267 __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
268 __ Lsa(address, address, key, kPointerSizeLog2 - kSmiTagSize);
269 __ sw(value, MemOperand(address));
270 // Update write barrier for the elements array address.
271 __ mov(scratch, value); // Preserve the value which is returned.
272 __ RecordWrite(elements, address, scratch, kRAHasNotBeenSaved,
273 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
274 __ Ret(USE_DELAY_SLOT);
275 __ Move(v0, value); // Ensure the stub returns correct value.
276
277 __ bind(fast_double);
278 if (check_map == kCheckMap) {
279 // Check for fast double array case. If this fails, call through to the
280 // runtime.
281 __ LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex);
282 __ Branch(slow, ne, elements_map, Operand(at));
283 }
284
285 // HOLECHECK: guards "A[i] double hole?"
286 // We have to see if the double version of the hole is present. If so
287 // go to the runtime.
288 __ Addu(address, elements, Operand(FixedDoubleArray::kHeaderSize +
289 kHoleNanUpper32Offset - kHeapObjectTag));
290 __ Lsa(address, address, key, kPointerSizeLog2);
291 __ lw(scratch, MemOperand(address));
292 __ Branch(&fast_double_without_map_check, ne, scratch,
293 Operand(kHoleNanUpper32));
294 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
295
296 __ bind(&fast_double_without_map_check);
297 __ StoreNumberToDoubleElements(value, key, elements, scratch, scratch2,
298 scratch3, &transition_double_elements);
299 if (increment_length == kIncrementLength) {
300 // Add 1 to receiver->length.
301 __ Addu(scratch, key, Operand(Smi::FromInt(1)));
302 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
303 }
304 __ Ret(USE_DELAY_SLOT);
305 __ Move(v0, value); // Ensure the stub returns correct value.
306
307 __ bind(&transition_smi_elements);
308 // Transition the array appropriately depending on the value type.
309 __ lw(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
310 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
311 __ Branch(&non_double_value, ne, scratch, Operand(at));
312
313 // Value is a double. Transition FAST_SMI_ELEMENTS ->
314 // FAST_DOUBLE_ELEMENTS and complete the store.
315 __ LoadTransitionedArrayMapConditional(
316 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
317 AllocationSiteMode mode =
318 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
319 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
320 receiver_map, mode, slow);
321 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
322 __ jmp(&fast_double_without_map_check);
323
324 __ bind(&non_double_value);
325 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
326 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
327 receiver_map, scratch, slow);
328 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
329 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
330 masm, receiver, key, value, receiver_map, mode, slow);
331 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
332 __ jmp(&finish_object_store);
333
334 __ bind(&transition_double_elements);
335 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
336 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
337 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
338 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
339 receiver_map, scratch, slow);
340 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
341 ElementsTransitionGenerator::GenerateDoubleToObject(
342 masm, receiver, key, value, receiver_map, mode, slow);
343 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
344 __ jmp(&finish_object_store);
345 }
346
347
348 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
349 LanguageMode language_mode) {
350 // ---------- S t a t e --------------
351 // -- a0 : value
352 // -- a1 : key
353 // -- a2 : receiver
354 // -- ra : return address
355 // -----------------------------------
356 Label slow, fast_object, fast_object_grow;
357 Label fast_double, fast_double_grow;
358 Label array, extra, check_if_double_array, maybe_name_key, miss;
359
360 // Register usage.
361 Register value = StoreDescriptor::ValueRegister();
362 Register key = StoreDescriptor::NameRegister();
363 Register receiver = StoreDescriptor::ReceiverRegister();
364 DCHECK(value.is(a0));
365 Register receiver_map = a3;
366 Register elements_map = t2;
367 Register elements = t3; // Elements array of the receiver.
368 // t0 and t1 are used as general scratch registers.
369
370 // Check that the key is a smi.
371 __ JumpIfNotSmi(key, &maybe_name_key);
372 // Check that the object isn't a smi.
373 __ JumpIfSmi(receiver, &slow);
374 // Get the map of the object.
375 __ lw(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
376 // Check that the receiver does not require access checks.
377 // The generic stub does not perform map checks.
378 __ lbu(t0, FieldMemOperand(receiver_map, Map::kBitFieldOffset));
379 __ And(t0, t0, Operand(1 << Map::kIsAccessCheckNeeded));
380 __ Branch(&slow, ne, t0, Operand(zero_reg));
381 // Check if the object is a JS array or not.
382 __ lbu(t0, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset));
383 __ Branch(&array, eq, t0, Operand(JS_ARRAY_TYPE));
384 // Check that the object is some kind of JS object EXCEPT JS Value type. In
385 // the case that the object is a value-wrapper object, we enter the runtime
386 // system to make sure that indexing into string objects works as intended.
387 STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE);
388 __ Branch(&slow, lo, t0, Operand(JS_OBJECT_TYPE));
389
390 // Object case: Check key against length in the elements array.
391 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
392 // Check array bounds. Both the key and the length of FixedArray are smis.
393 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
394 __ Branch(&fast_object, lo, key, Operand(t0));
395
396 // Slow case, handle jump to runtime.
397 __ bind(&slow);
398 // Entry registers are intact.
399 // a0: value.
400 // a1: key.
401 // a2: receiver.
402 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode);
403 // Never returns to here.
404
405 __ bind(&maybe_name_key);
406 __ lw(t0, FieldMemOperand(key, HeapObject::kMapOffset));
407 __ lb(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
408 __ JumpIfNotUniqueNameInstanceType(t0, &slow);
409
410 // The handlers in the stub cache expect a vector and slot. Since we won't
411 // change the IC from any downstream misses, a dummy vector can be used.
412 Register vector = StoreWithVectorDescriptor::VectorRegister();
413 Register slot = StoreWithVectorDescriptor::SlotRegister();
414 DCHECK(!AreAliased(vector, slot, t1, t2, t4, t5));
415 Handle<TypeFeedbackVector> dummy_vector =
416 TypeFeedbackVector::DummyVector(masm->isolate());
417 int slot_index = dummy_vector->GetIndex(
418 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
419 __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
420 __ li(slot, Operand(Smi::FromInt(slot_index)));
421
422 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, t1,
423 t2, t4, t5);
424 // Cache miss.
425 __ Branch(&miss);
426
427 // Extra capacity case: Check if there is extra capacity to
428 // perform the store and update the length. Used for adding one
429 // element to the array by writing to array[array.length].
430 __ bind(&extra);
431 // Condition code from comparing key and array length is still available.
432 // Only support writing to array[array.length].
433 __ Branch(&slow, ne, key, Operand(t0));
434 // Check for room in the elements backing store.
435 // Both the key and the length of FixedArray are smis.
436 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
437 __ Branch(&slow, hs, key, Operand(t0));
438 __ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
439 __ Branch(&check_if_double_array, ne, elements_map,
440 Heap::kFixedArrayMapRootIndex);
441
442 __ jmp(&fast_object_grow);
443
444 __ bind(&check_if_double_array);
445 __ Branch(&slow, ne, elements_map, Heap::kFixedDoubleArrayMapRootIndex);
446 __ jmp(&fast_double_grow);
447
448 // Array case: Get the length and the elements array from the JS
449 // array. Check that the array is in fast mode (and writable); if it
450 // is the length is always a smi.
451 __ bind(&array);
452 __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
453
454 // Check the key against the length in the array.
455 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
456 __ Branch(&extra, hs, key, Operand(t0));
457
458 KeyedStoreGenerateMegamorphicHelper(
459 masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
460 value, key, receiver, receiver_map, elements_map, elements);
461 KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
462 &fast_double_grow, &slow, kDontCheckMap,
463 kIncrementLength, value, key, receiver,
464 receiver_map, elements_map, elements);
465
466 __ bind(&miss);
467 GenerateMiss(masm);
468 }
469
470
471 static void StoreIC_PushArgs(MacroAssembler* masm) { 203 static void StoreIC_PushArgs(MacroAssembler* masm) {
472 __ Push(StoreWithVectorDescriptor::ValueRegister(), 204 __ Push(StoreWithVectorDescriptor::ValueRegister(),
473 StoreWithVectorDescriptor::SlotRegister(), 205 StoreWithVectorDescriptor::SlotRegister(),
474 StoreWithVectorDescriptor::VectorRegister(), 206 StoreWithVectorDescriptor::VectorRegister(),
475 StoreWithVectorDescriptor::ReceiverRegister(), 207 StoreWithVectorDescriptor::ReceiverRegister(),
476 StoreWithVectorDescriptor::NameRegister()); 208 StoreWithVectorDescriptor::NameRegister());
477 } 209 }
478 210
479 211
480 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 212 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 break; 380 break;
649 default: 381 default:
650 UNIMPLEMENTED(); 382 UNIMPLEMENTED();
651 } 383 }
652 patcher.ChangeBranchCondition(branch_instr, opcode); 384 patcher.ChangeBranchCondition(branch_instr, opcode);
653 } 385 }
654 } // namespace internal 386 } // namespace internal
655 } // namespace v8 387 } // namespace v8
656 388
657 #endif // V8_TARGET_ARCH_MIPS 389 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic/mips/ic-compiler-mips.cc ('k') | src/ic/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698