OLD | NEW |
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 | 5 |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS | 9 #if V8_TARGET_ARCH_MIPS |
10 | 10 |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 __ bind(&unique); | 315 __ bind(&unique); |
316 } | 316 } |
317 | 317 |
318 | 318 |
319 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 319 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
320 // ----------- S t a t e ------------- | 320 // ----------- S t a t e ------------- |
321 // -- a2 : name | 321 // -- a2 : name |
322 // -- ra : return address | 322 // -- ra : return address |
323 // -- a0 : receiver | 323 // -- a0 : receiver |
324 // ----------------------------------- | 324 // ----------------------------------- |
| 325 ASSERT(a0.is(ReceiverRegister())); |
| 326 ASSERT(a2.is(NameRegister())); |
325 | 327 |
326 // Probe the stub cache. | 328 // Probe the stub cache. |
327 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 329 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
328 masm->isolate()->stub_cache()->GenerateProbe( | 330 masm->isolate()->stub_cache()->GenerateProbe( |
329 masm, flags, a0, a2, a3, t0, t1, t2); | 331 masm, flags, a0, a2, a3, t0, t1, t2); |
330 | 332 |
331 // Cache miss: Jump to runtime. | 333 // Cache miss: Jump to runtime. |
332 GenerateMiss(masm); | 334 GenerateMiss(masm); |
333 } | 335 } |
334 | 336 |
335 | 337 |
336 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 338 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
337 // ----------- S t a t e ------------- | 339 // ----------- S t a t e ------------- |
338 // -- a2 : name | 340 // -- a2 : name |
339 // -- lr : return address | 341 // -- lr : return address |
340 // -- a0 : receiver | 342 // -- a0 : receiver |
341 // ----------------------------------- | 343 // ----------------------------------- |
| 344 ASSERT(a0.is(ReceiverRegister())); |
| 345 ASSERT(a2.is(NameRegister())); |
| 346 |
342 Label miss, slow; | 347 Label miss, slow; |
343 | 348 |
344 GenerateNameDictionaryReceiverCheck(masm, a0, a1, a3, t0, &miss); | 349 GenerateNameDictionaryReceiverCheck(masm, a0, a1, a3, t0, &miss); |
345 | 350 |
346 // a1: elements | 351 // a1: elements |
347 GenerateDictionaryLoad(masm, &slow, a1, a2, v0, a3, t0); | 352 GenerateDictionaryLoad(masm, &slow, a1, a2, v0, a3, t0); |
348 __ Ret(); | 353 __ Ret(); |
349 | 354 |
350 // Dictionary load failed, go slow (but don't miss). | 355 // Dictionary load failed, go slow (but don't miss). |
351 __ bind(&slow); | 356 __ bind(&slow); |
352 GenerateRuntimeGetProperty(masm); | 357 GenerateRuntimeGetProperty(masm); |
353 | 358 |
354 // Cache miss: Jump to runtime. | 359 // Cache miss: Jump to runtime. |
355 __ bind(&miss); | 360 __ bind(&miss); |
356 GenerateMiss(masm); | 361 GenerateMiss(masm); |
357 } | 362 } |
358 | 363 |
359 | 364 |
| 365 // A register that isn't one of the parameters to the load ic. |
| 366 static const Register LoadIC_TempRegister() { return a3; } |
| 367 |
| 368 |
360 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 369 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
361 // ----------- S t a t e ------------- | 370 // The return address is on the stack. |
362 // -- a2 : name | |
363 // -- ra : return address | |
364 // -- a0 : receiver | |
365 // ----------------------------------- | |
366 Isolate* isolate = masm->isolate(); | 371 Isolate* isolate = masm->isolate(); |
367 | 372 |
368 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); | 373 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); |
369 | 374 |
370 __ mov(a3, a0); | 375 __ mov(LoadIC_TempRegister(), ReceiverRegister()); |
371 __ Push(a3, a2); | 376 __ Push(LoadIC_TempRegister(), NameRegister()); |
372 | 377 |
373 // Perform tail call to the entry. | 378 // Perform tail call to the entry. |
374 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); | 379 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); |
375 __ TailCallExternalReference(ref, 2, 1); | 380 __ TailCallExternalReference(ref, 2, 1); |
376 } | 381 } |
377 | 382 |
378 | 383 |
379 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 384 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
380 // ---------- S t a t e -------------- | 385 // The return address is on the stack. |
381 // -- a2 : name | |
382 // -- ra : return address | |
383 // -- a0 : receiver | |
384 // ----------------------------------- | |
385 | 386 |
386 __ mov(a3, a0); | 387 __ mov(LoadIC_TempRegister(), ReceiverRegister()); |
387 __ Push(a3, a2); | 388 __ Push(LoadIC_TempRegister(), NameRegister()); |
388 | 389 |
389 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); | 390 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); |
390 } | 391 } |
391 | 392 |
392 | 393 |
393 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm, | 394 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm, |
394 Register object, | 395 Register object, |
395 Register key, | 396 Register key, |
396 Register scratch1, | 397 Register scratch1, |
397 Register scratch2, | 398 Register scratch2, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 return MemOperand(scratch); | 480 return MemOperand(scratch); |
480 } | 481 } |
481 | 482 |
482 | 483 |
483 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 484 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
484 // ---------- S t a t e -------------- | 485 // ---------- S t a t e -------------- |
485 // -- lr : return address | 486 // -- lr : return address |
486 // -- a0 : key | 487 // -- a0 : key |
487 // -- a1 : receiver | 488 // -- a1 : receiver |
488 // ----------------------------------- | 489 // ----------------------------------- |
| 490 ASSERT(a1.is(ReceiverRegister())); |
| 491 ASSERT(a0.is(NameRegister())); |
489 Label slow, notin; | 492 Label slow, notin; |
490 MemOperand mapped_location = | 493 MemOperand mapped_location = |
491 GenerateMappedArgumentsLookup(masm, a1, a0, a2, a3, t0, ¬in, &slow); | 494 GenerateMappedArgumentsLookup(masm, a1, a0, a2, a3, t0, ¬in, &slow); |
492 __ Ret(USE_DELAY_SLOT); | 495 __ Ret(USE_DELAY_SLOT); |
493 __ lw(v0, mapped_location); | 496 __ lw(v0, mapped_location); |
494 __ bind(¬in); | 497 __ bind(¬in); |
495 // The unmapped lookup expects that the parameter map is in a2. | 498 // The unmapped lookup expects that the parameter map is in a2. |
496 MemOperand unmapped_location = | 499 MemOperand unmapped_location = |
497 GenerateUnmappedArgumentsLookup(masm, a0, a2, a3, &slow); | 500 GenerateUnmappedArgumentsLookup(masm, a0, a2, a3, &slow); |
498 __ lw(a2, unmapped_location); | 501 __ lw(a2, unmapped_location); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 __ RecordWrite(a3, unmapped_location.rm(), t5, | 537 __ RecordWrite(a3, unmapped_location.rm(), t5, |
535 kRAHasNotBeenSaved, kDontSaveFPRegs); | 538 kRAHasNotBeenSaved, kDontSaveFPRegs); |
536 __ Ret(USE_DELAY_SLOT); | 539 __ Ret(USE_DELAY_SLOT); |
537 __ mov(v0, a0); // (In delay slot) return the value stored in v0. | 540 __ mov(v0, a0); // (In delay slot) return the value stored in v0. |
538 __ bind(&slow); | 541 __ bind(&slow); |
539 GenerateMiss(masm); | 542 GenerateMiss(masm); |
540 } | 543 } |
541 | 544 |
542 | 545 |
543 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 546 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
544 // ---------- S t a t e -------------- | 547 // The return address is on the stack. |
545 // -- ra : return address | |
546 // -- a0 : key | |
547 // -- a1 : receiver | |
548 // ----------------------------------- | |
549 Isolate* isolate = masm->isolate(); | 548 Isolate* isolate = masm->isolate(); |
550 | 549 |
551 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); | 550 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0); |
552 | 551 |
553 __ Push(a1, a0); | 552 __ Push(ReceiverRegister(), NameRegister()); |
554 | 553 |
555 // Perform tail call to the entry. | 554 // Perform tail call to the entry. |
556 ExternalReference ref = | 555 ExternalReference ref = |
557 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); | 556 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); |
558 | 557 |
559 __ TailCallExternalReference(ref, 2, 1); | 558 __ TailCallExternalReference(ref, 2, 1); |
560 } | 559 } |
561 | 560 |
562 | 561 |
563 // IC register specifications | 562 // IC register specifications |
564 const Register LoadIC::ReceiverRegister() { return a0; } | 563 const Register LoadIC::ReceiverRegister() { return a0; } |
565 const Register LoadIC::NameRegister() { return a2; } | 564 const Register LoadIC::NameRegister() { return a2; } |
566 const Register KeyedLoadIC::ReceiverRegister() { return a1; } | 565 const Register KeyedLoadIC::ReceiverRegister() { return a1; } |
567 const Register KeyedLoadIC::NameRegister() { return a0; } | 566 const Register KeyedLoadIC::NameRegister() { return a0; } |
568 | 567 |
569 | 568 |
570 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 569 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
571 // ---------- S t a t e -------------- | 570 // The return address is on the stack. |
572 // -- ra : return address | |
573 // -- a0 : key | |
574 // -- a1 : receiver | |
575 // ----------------------------------- | |
576 | 571 |
577 __ Push(a1, a0); | 572 __ Push(ReceiverRegister(), NameRegister()); |
578 | 573 |
579 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 574 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
580 } | 575 } |
581 | 576 |
582 | 577 |
583 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 578 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
584 // ---------- S t a t e -------------- | 579 // ---------- S t a t e -------------- |
585 // -- ra : return address | 580 // -- ra : return address |
586 // -- a0 : key | 581 // -- a0 : key |
587 // -- a1 : receiver | 582 // -- a1 : receiver |
588 // ----------------------------------- | 583 // ----------------------------------- |
589 Label slow, check_name, index_smi, index_name, property_array_property; | 584 Label slow, check_name, index_smi, index_name, property_array_property; |
590 Label probe_dictionary, check_number_dictionary; | 585 Label probe_dictionary, check_number_dictionary; |
591 | 586 |
592 Register key = a0; | 587 Register key = NameRegister(); |
593 Register receiver = a1; | 588 Register receiver = ReceiverRegister(); |
| 589 ASSERT(key.is(a0)); |
| 590 ASSERT(receiver.is(a1)); |
594 | 591 |
595 Isolate* isolate = masm->isolate(); | 592 Isolate* isolate = masm->isolate(); |
596 | 593 |
597 // Check that the key is a smi. | 594 // Check that the key is a smi. |
598 __ JumpIfNotSmi(key, &check_name); | 595 __ JumpIfNotSmi(key, &check_name); |
599 __ bind(&index_smi); | 596 __ bind(&index_smi); |
600 // Now the key is known to be a smi. This place is also jumped to from below | 597 // Now the key is known to be a smi. This place is also jumped to from below |
601 // where a numeric string is converted to a smi. | 598 // where a numeric string is converted to a smi. |
602 | 599 |
603 GenerateKeyedLoadReceiverCheck( | 600 GenerateKeyedLoadReceiverCheck( |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 __ Ret(); | 749 __ Ret(); |
753 | 750 |
754 __ bind(&index_name); | 751 __ bind(&index_name); |
755 __ IndexFromHash(a3, key); | 752 __ IndexFromHash(a3, key); |
756 // Now jump to the place where smi keys are handled. | 753 // Now jump to the place where smi keys are handled. |
757 __ Branch(&index_smi); | 754 __ Branch(&index_smi); |
758 } | 755 } |
759 | 756 |
760 | 757 |
761 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 758 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
762 // ---------- S t a t e -------------- | 759 // Return address is on the stack. |
763 // -- ra : return address | |
764 // -- a0 : key (index) | |
765 // -- a1 : receiver | |
766 // ----------------------------------- | |
767 Label miss; | 760 Label miss; |
768 | 761 |
769 Register receiver = a1; | 762 Register receiver = ReceiverRegister(); |
770 Register index = a0; | 763 Register index = NameRegister(); |
771 Register scratch = a3; | 764 Register scratch = a3; |
772 Register result = v0; | 765 Register result = v0; |
| 766 ASSERT(!scratch.is(receiver) && !scratch.is(index)); |
773 | 767 |
774 StringCharAtGenerator char_at_generator(receiver, | 768 StringCharAtGenerator char_at_generator(receiver, |
775 index, | 769 index, |
776 scratch, | 770 scratch, |
777 result, | 771 result, |
778 &miss, // When not a string. | 772 &miss, // When not a string. |
779 &miss, // When not a number. | 773 &miss, // When not a number. |
780 &miss, // When index out of range. | 774 &miss, // When index out of range. |
781 STRING_INDEX_IS_ARRAY_INDEX); | 775 STRING_INDEX_IS_ARRAY_INDEX); |
782 char_at_generator.GenerateFast(masm); | 776 char_at_generator.GenerateFast(masm); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 value, key, receiver, receiver_map, | 1065 value, key, receiver, receiver_map, |
1072 elements_map, elements); | 1066 elements_map, elements); |
1073 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 1067 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
1074 &slow, kDontCheckMap, kIncrementLength, | 1068 &slow, kDontCheckMap, kIncrementLength, |
1075 value, key, receiver, receiver_map, | 1069 value, key, receiver, receiver_map, |
1076 elements_map, elements); | 1070 elements_map, elements); |
1077 } | 1071 } |
1078 | 1072 |
1079 | 1073 |
1080 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 1074 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
1081 // ---------- S t a t e -------------- | 1075 // Return address is on the stack. |
1082 // -- ra : return address | |
1083 // -- a0 : key | |
1084 // -- a1 : receiver | |
1085 // ----------------------------------- | |
1086 Label slow; | 1076 Label slow; |
1087 | 1077 |
| 1078 Register receiver = ReceiverRegister(); |
| 1079 Register key = NameRegister(); |
| 1080 Register scratch1 = a2; |
| 1081 Register scratch2 = a3; |
| 1082 ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); |
| 1083 ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); |
| 1084 |
1088 // Check that the receiver isn't a smi. | 1085 // Check that the receiver isn't a smi. |
1089 __ JumpIfSmi(a1, &slow); | 1086 __ JumpIfSmi(receiver, &slow); |
1090 | 1087 |
1091 // Check that the key is an array index, that is Uint32. | 1088 // Check that the key is an array index, that is Uint32. |
1092 __ And(t0, a0, Operand(kSmiTagMask | kSmiSignMask)); | 1089 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); |
1093 __ Branch(&slow, ne, t0, Operand(zero_reg)); | 1090 __ Branch(&slow, ne, t0, Operand(zero_reg)); |
1094 | 1091 |
1095 // Get the map of the receiver. | 1092 // Get the map of the receiver. |
1096 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 1093 __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
1097 | 1094 |
1098 // Check that it has indexed interceptor and access checks | 1095 // Check that it has indexed interceptor and access checks |
1099 // are not enabled for this object. | 1096 // are not enabled for this object. |
1100 __ lbu(a3, FieldMemOperand(a2, Map::kBitFieldOffset)); | 1097 __ lbu(scratch2, FieldMemOperand(scratch1, Map::kBitFieldOffset)); |
1101 __ And(a3, a3, Operand(kSlowCaseBitFieldMask)); | 1098 __ And(scratch2, scratch2, Operand(kSlowCaseBitFieldMask)); |
1102 __ Branch(&slow, ne, a3, Operand(1 << Map::kHasIndexedInterceptor)); | 1099 __ Branch(&slow, ne, scratch2, Operand(1 << Map::kHasIndexedInterceptor)); |
1103 // Everything is fine, call runtime. | 1100 // Everything is fine, call runtime. |
1104 __ Push(a1, a0); // Receiver, key. | 1101 __ Push(receiver, key); // Receiver, key. |
1105 | 1102 |
1106 // Perform tail call to the entry. | 1103 // Perform tail call to the entry. |
1107 __ TailCallExternalReference(ExternalReference( | 1104 __ TailCallExternalReference(ExternalReference( |
1108 IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); | 1105 IC_Utility(kKeyedLoadPropertyWithInterceptor), masm->isolate()), 2, 1); |
1109 | 1106 |
1110 __ bind(&slow); | 1107 __ bind(&slow); |
1111 GenerateMiss(masm); | 1108 GenerateMiss(masm); |
1112 } | 1109 } |
1113 | 1110 |
1114 | 1111 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 } else { | 1335 } else { |
1339 ASSERT(Assembler::IsBne(branch_instr)); | 1336 ASSERT(Assembler::IsBne(branch_instr)); |
1340 patcher.ChangeBranchCondition(eq); | 1337 patcher.ChangeBranchCondition(eq); |
1341 } | 1338 } |
1342 } | 1339 } |
1343 | 1340 |
1344 | 1341 |
1345 } } // namespace v8::internal | 1342 } } // namespace v8::internal |
1346 | 1343 |
1347 #endif // V8_TARGET_ARCH_MIPS | 1344 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |