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

Side by Side Diff: src/ic/s390/ic-s390.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/s390/ic-compiler-s390.cc ('k') | src/ic/s390/stub-cache-s390.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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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_S390 5 #if V8_TARGET_ARCH_S390
6 6
7 #include "src/ic/ic.h" 7 #include "src/ic/ic.h"
8 #include "src/codegen.h" 8 #include "src/codegen.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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 } 209 }
210 210
211 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 211 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
212 StoreIC_PushArgs(masm); 212 StoreIC_PushArgs(masm);
213 213
214 // The slow case calls into the runtime to complete the store without causing 214 // The slow case calls into the runtime to complete the store without causing
215 // an IC miss that would otherwise cause a transition to the generic stub. 215 // an IC miss that would otherwise cause a transition to the generic stub.
216 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); 216 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow);
217 } 217 }
218 218
219 static void KeyedStoreGenerateMegamorphicHelper(
220 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
221 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
222 Register value, Register key, Register receiver, Register receiver_map,
223 Register elements_map, Register elements) {
224 Label transition_smi_elements;
225 Label finish_object_store, non_double_value, transition_double_elements;
226 Label fast_double_without_map_check;
227
228 // Fast case: Do the store, could be either Object or double.
229 __ bind(fast_object);
230 Register scratch = r6;
231 Register address = r7;
232 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
233 scratch, address));
234
235 if (check_map == kCheckMap) {
236 __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
237 __ CmpP(elements_map,
238 Operand(masm->isolate()->factory()->fixed_array_map()));
239 __ bne(fast_double);
240 }
241
242 // HOLECHECK: guards "A[i] = V"
243 // We have to go to the runtime if the current value is the hole because
244 // there may be a callback on the element
245 Label holecheck_passed1;
246 // @TODO(joransiu) : Fold AddP into memref of LoadP
247 __ AddP(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
248 __ SmiToPtrArrayOffset(scratch, key);
249 __ LoadP(scratch, MemOperand(address, scratch));
250 __ CmpP(scratch, Operand(masm->isolate()->factory()->the_hole_value()));
251 __ bne(&holecheck_passed1, Label::kNear);
252 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
253
254 __ bind(&holecheck_passed1);
255
256 // Smi stores don't require further checks.
257 Label non_smi_value;
258 __ JumpIfNotSmi(value, &non_smi_value);
259
260 if (increment_length == kIncrementLength) {
261 // Add 1 to receiver->length.
262 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), r0);
263 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
264 }
265 // It's irrelevant whether array is smi-only or not when writing a smi.
266 __ AddP(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
267 __ SmiToPtrArrayOffset(scratch, key);
268 __ StoreP(value, MemOperand(address, scratch));
269 __ Ret();
270
271 __ bind(&non_smi_value);
272 // Escape to elements kind transition case.
273 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
274
275 // Fast elements array, store the value to the elements backing store.
276 __ bind(&finish_object_store);
277 if (increment_length == kIncrementLength) {
278 // Add 1 to receiver->length.
279 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), r0);
280 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
281 }
282 __ AddP(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
283 __ SmiToPtrArrayOffset(scratch, key);
284 __ StoreP(value, MemOperand(address, scratch));
285 __ la(address, MemOperand(address, scratch));
286 // Update write barrier for the elements array address.
287 __ LoadRR(scratch, value); // Preserve the value which is returned.
288 __ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved,
289 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
290 __ Ret();
291
292 __ bind(fast_double);
293 if (check_map == kCheckMap) {
294 // Check for fast double array case. If this fails, call through to the
295 // runtime.
296 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
297 __ bne(slow);
298 }
299
300 // HOLECHECK: guards "A[i] double hole?"
301 // We have to see if the double version of the hole is present. If so
302 // go to the runtime.
303 // @TODO(joransiu) : Fold AddP Operand into LoadlW
304 __ AddP(address, elements,
305 Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset -
306 kHeapObjectTag)));
307 __ SmiToDoubleArrayOffset(scratch, key);
308 __ LoadlW(scratch, MemOperand(address, scratch));
309 __ CmpP(scratch, Operand(kHoleNanUpper32));
310 __ bne(&fast_double_without_map_check, Label::kNear);
311 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
312
313 __ bind(&fast_double_without_map_check);
314 __ StoreNumberToDoubleElements(value, key, elements, scratch, d0,
315 &transition_double_elements);
316 if (increment_length == kIncrementLength) {
317 // Add 1 to receiver->length.
318 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), r0);
319 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
320 }
321 __ Ret();
322
323 __ bind(&transition_smi_elements);
324 // Transition the array appropriately depending on the value type.
325 __ LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
326 __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
327 __ bne(&non_double_value);
328
329 // Value is a double. Transition FAST_SMI_ELEMENTS ->
330 // FAST_DOUBLE_ELEMENTS and complete the store.
331 __ LoadTransitionedArrayMapConditional(
332 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
333 AllocationSiteMode mode =
334 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
335 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
336 receiver_map, mode, slow);
337 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
338 __ b(&fast_double_without_map_check);
339
340 __ bind(&non_double_value);
341 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
342 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
343 receiver_map, scratch, slow);
344 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
345 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
346 masm, receiver, key, value, receiver_map, mode, slow);
347 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
348 __ b(&finish_object_store);
349
350 __ bind(&transition_double_elements);
351 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
352 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
353 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
354 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
355 receiver_map, scratch, slow);
356 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
357 ElementsTransitionGenerator::GenerateDoubleToObject(
358 masm, receiver, key, value, receiver_map, mode, slow);
359 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
360 __ b(&finish_object_store);
361 }
362
363 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
364 LanguageMode language_mode) {
365 // ---------- S t a t e --------------
366 // -- r2 : value
367 // -- r3 : key
368 // -- r4 : receiver
369 // -- lr : return address
370 // -----------------------------------
371 Label slow, fast_object, fast_object_grow;
372 Label fast_double, fast_double_grow;
373 Label array, extra, check_if_double_array, maybe_name_key, miss;
374
375 // Register usage.
376 Register value = StoreDescriptor::ValueRegister();
377 Register key = StoreDescriptor::NameRegister();
378 Register receiver = StoreDescriptor::ReceiverRegister();
379 DCHECK(receiver.is(r3));
380 DCHECK(key.is(r4));
381 DCHECK(value.is(r2));
382 Register receiver_map = r5;
383 Register elements_map = r8;
384 Register elements = r9; // Elements array of the receiver.
385 // r6 and r7 are used as general scratch registers.
386
387 // Check that the key is a smi.
388 __ JumpIfNotSmi(key, &maybe_name_key);
389 // Check that the object isn't a smi.
390 __ JumpIfSmi(receiver, &slow);
391 // Get the map of the object.
392 __ LoadP(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
393 // Check that the receiver does not require access checks.
394 // The generic stub does not perform map checks.
395 __ LoadlB(ip, FieldMemOperand(receiver_map, Map::kBitFieldOffset));
396 __ AndP(r0, ip, Operand(1 << Map::kIsAccessCheckNeeded));
397 __ bne(&slow, Label::kNear);
398 // Check if the object is a JS array or not.
399 __ LoadlB(r6, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset));
400 __ CmpP(r6, Operand(JS_ARRAY_TYPE));
401 __ beq(&array);
402 // Check that the object is some kind of JSObject.
403 __ CmpP(r6, Operand(FIRST_JS_OBJECT_TYPE));
404 __ blt(&slow, Label::kNear);
405
406 // Object case: Check key against length in the elements array.
407 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
408 // Check array bounds. Both the key and the length of FixedArray are smis.
409 __ CmpLogicalP(key, FieldMemOperand(elements, FixedArray::kLengthOffset));
410 __ blt(&fast_object);
411
412 // Slow case, handle jump to runtime.
413 __ bind(&slow);
414 // Entry registers are intact.
415 // r2: value.
416 // r3: key.
417 // r4: receiver.
418 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode);
419 // Never returns to here.
420
421 __ bind(&maybe_name_key);
422 __ LoadP(r6, FieldMemOperand(key, HeapObject::kMapOffset));
423 __ LoadlB(r6, FieldMemOperand(r6, Map::kInstanceTypeOffset));
424 __ JumpIfNotUniqueNameInstanceType(r6, &slow);
425
426 // The handlers in the stub cache expect a vector and slot. Since we won't
427 // change the IC from any downstream misses, a dummy vector can be used.
428 Register vector = StoreWithVectorDescriptor::VectorRegister();
429 Register slot = StoreWithVectorDescriptor::SlotRegister();
430 DCHECK(!AreAliased(vector, slot, r7, r8, r9, ip));
431 Handle<TypeFeedbackVector> dummy_vector =
432 TypeFeedbackVector::DummyVector(masm->isolate());
433 int slot_index = dummy_vector->GetIndex(
434 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot));
435 __ LoadRoot(vector, Heap::kDummyVectorRootIndex);
436 __ LoadSmiLiteral(slot, Smi::FromInt(slot_index));
437
438 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, r7,
439 r8, r9, ip);
440 // Cache miss.
441 __ b(&miss);
442
443 // Extra capacity case: Check if there is extra capacity to
444 // perform the store and update the length. Used for adding one
445 // element to the array by writing to array[array.length].
446 __ bind(&extra);
447 // Condition code from comparing key and array length is still available.
448 __ bne(&slow); // Only support writing to writing to array[array.length].
449 // Check for room in the elements backing store.
450 // Both the key and the length of FixedArray are smis.
451 __ CmpLogicalP(key, FieldMemOperand(elements, FixedArray::kLengthOffset));
452 __ bge(&slow);
453 __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
454 __ CmpP(elements_map, Operand(masm->isolate()->factory()->fixed_array_map()));
455 __ bne(&check_if_double_array, Label::kNear);
456 __ b(&fast_object_grow);
457
458 __ bind(&check_if_double_array);
459 __ CmpP(elements_map,
460 Operand(masm->isolate()->factory()->fixed_double_array_map()));
461 __ bne(&slow);
462 __ b(&fast_double_grow);
463
464 // Array case: Get the length and the elements array from the JS
465 // array. Check that the array is in fast mode (and writable); if it
466 // is the length is always a smi.
467 __ bind(&array);
468 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
469
470 // Check the key against the length in the array.
471 __ CmpLogicalP(key, FieldMemOperand(receiver, JSArray::kLengthOffset));
472 __ bge(&extra);
473
474 KeyedStoreGenerateMegamorphicHelper(
475 masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
476 value, key, receiver, receiver_map, elements_map, elements);
477 KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
478 &fast_double_grow, &slow, kDontCheckMap,
479 kIncrementLength, value, key, receiver,
480 receiver_map, elements_map, elements);
481 __ bind(&miss);
482 GenerateMiss(masm);
483 }
484
485 void StoreIC::GenerateMiss(MacroAssembler* masm) { 219 void StoreIC::GenerateMiss(MacroAssembler* masm) {
486 StoreIC_PushArgs(masm); 220 StoreIC_PushArgs(masm);
487 221
488 // Perform tail call to the entry. 222 // Perform tail call to the entry.
489 __ TailCallRuntime(Runtime::kStoreIC_Miss); 223 __ TailCallRuntime(Runtime::kStoreIC_Miss);
490 } 224 }
491 225
492 void StoreIC::GenerateNormal(MacroAssembler* masm) { 226 void StoreIC::GenerateNormal(MacroAssembler* masm) {
493 Label miss; 227 Label miss;
494 Register receiver = StoreDescriptor::ReceiverRegister(); 228 Register receiver = StoreDescriptor::ReceiverRegister();
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 patcher.masm()->brcl(cc, Operand((branch_instr & 0xffffffff) << 1)); 367 patcher.masm()->brcl(cc, Operand((branch_instr & 0xffffffff) << 1));
634 } else { 368 } else {
635 DCHECK(false); 369 DCHECK(false);
636 } 370 }
637 } 371 }
638 372
639 } // namespace internal 373 } // namespace internal
640 } // namespace v8 374 } // namespace v8
641 375
642 #endif // V8_TARGET_ARCH_S390 376 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/ic/s390/ic-compiler-s390.cc ('k') | src/ic/s390/stub-cache-s390.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698