| 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 165 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 166 // Check bit field. | 166 // Check bit field. |
| 167 __ lbu(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 167 __ lbu(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 168 __ And(at, scratch, | 168 __ And(at, scratch, |
| 169 Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit))); | 169 Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit))); |
| 170 __ Branch(slow, ne, at, Operand(zero_reg)); | 170 __ Branch(slow, ne, at, Operand(zero_reg)); |
| 171 // Check that the object is some kind of JS object EXCEPT JS Value type. | 171 // Check that the object is some kind of JS object EXCEPT JS Value type. |
| 172 // In the case that the object is a value-wrapper object, | 172 // In the case that the object is a value-wrapper object, |
| 173 // we enter the runtime system to make sure that indexing into string | 173 // we enter the runtime system to make sure that indexing into string |
| 174 // objects work as intended. | 174 // objects work as intended. |
| 175 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 175 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); |
| 176 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 176 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
| 177 __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE)); | 177 __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE)); |
| 178 } | 178 } |
| 179 | 179 |
| 180 | 180 |
| 181 // Loads an indexed element from a fast case array. | 181 // Loads an indexed element from a fast case array. |
| 182 // If not_fast_array is NULL, doesn't perform the elements map check. | 182 // If not_fast_array is NULL, doesn't perform the elements map check. |
| 183 static void GenerateFastArrayLoad(MacroAssembler* masm, | 183 static void GenerateFastArrayLoad(MacroAssembler* masm, |
| 184 Register receiver, | 184 Register receiver, |
| 185 Register key, | 185 Register key, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 __ Branch(not_unique, ne, at, Operand(zero_reg)); | 272 __ Branch(not_unique, ne, at, Operand(zero_reg)); |
| 273 | 273 |
| 274 __ bind(&unique); | 274 __ bind(&unique); |
| 275 } | 275 } |
| 276 | 276 |
| 277 | 277 |
| 278 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 278 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 279 // The return address is in lr. | 279 // The return address is in lr. |
| 280 Register receiver = ReceiverRegister(); | 280 Register receiver = ReceiverRegister(); |
| 281 Register name = NameRegister(); | 281 Register name = NameRegister(); |
| 282 ASSERT(receiver.is(a1)); | 282 DCHECK(receiver.is(a1)); |
| 283 ASSERT(name.is(a2)); | 283 DCHECK(name.is(a2)); |
| 284 | 284 |
| 285 // Probe the stub cache. | 285 // Probe the stub cache. |
| 286 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 286 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 287 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 287 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 288 masm->isolate()->stub_cache()->GenerateProbe( | 288 masm->isolate()->stub_cache()->GenerateProbe( |
| 289 masm, flags, receiver, name, a3, t0, t1, t2); | 289 masm, flags, receiver, name, a3, t0, t1, t2); |
| 290 | 290 |
| 291 // Cache miss: Jump to runtime. | 291 // Cache miss: Jump to runtime. |
| 292 GenerateMiss(masm); | 292 GenerateMiss(masm); |
| 293 } | 293 } |
| 294 | 294 |
| 295 | 295 |
| 296 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 296 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 297 Register dictionary = a0; | 297 Register dictionary = a0; |
| 298 ASSERT(!dictionary.is(ReceiverRegister())); | 298 DCHECK(!dictionary.is(ReceiverRegister())); |
| 299 ASSERT(!dictionary.is(NameRegister())); | 299 DCHECK(!dictionary.is(NameRegister())); |
| 300 | 300 |
| 301 Label slow; | 301 Label slow; |
| 302 | 302 |
| 303 __ lw(dictionary, | 303 __ lw(dictionary, |
| 304 FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 304 FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
| 305 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, t0); | 305 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, t0); |
| 306 __ Ret(); | 306 __ Ret(); |
| 307 | 307 |
| 308 // Dictionary load failed, go slow (but don't miss). | 308 // Dictionary load failed, go slow (but don't miss). |
| 309 __ bind(&slow); | 309 __ bind(&slow); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 427 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 428 __ Addu(scratch, backing_store, scratch); | 428 __ Addu(scratch, backing_store, scratch); |
| 429 return MemOperand(scratch); | 429 return MemOperand(scratch); |
| 430 } | 430 } |
| 431 | 431 |
| 432 | 432 |
| 433 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 433 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 434 // The return address is in ra. | 434 // The return address is in ra. |
| 435 Register receiver = ReceiverRegister(); | 435 Register receiver = ReceiverRegister(); |
| 436 Register key = NameRegister(); | 436 Register key = NameRegister(); |
| 437 ASSERT(receiver.is(a1)); | 437 DCHECK(receiver.is(a1)); |
| 438 ASSERT(key.is(a2)); | 438 DCHECK(key.is(a2)); |
| 439 | 439 |
| 440 Label slow, notin; | 440 Label slow, notin; |
| 441 MemOperand mapped_location = | 441 MemOperand mapped_location = |
| 442 GenerateMappedArgumentsLookup( | 442 GenerateMappedArgumentsLookup( |
| 443 masm, receiver, key, a0, a3, t0, ¬in, &slow); | 443 masm, receiver, key, a0, a3, t0, ¬in, &slow); |
| 444 __ Ret(USE_DELAY_SLOT); | 444 __ Ret(USE_DELAY_SLOT); |
| 445 __ lw(v0, mapped_location); | 445 __ lw(v0, mapped_location); |
| 446 __ bind(¬in); | 446 __ bind(¬in); |
| 447 // The unmapped lookup expects that the parameter map is in a0. | 447 // The unmapped lookup expects that the parameter map is in a0. |
| 448 MemOperand unmapped_location = | 448 MemOperand unmapped_location = |
| 449 GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow); | 449 GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow); |
| 450 __ lw(a0, unmapped_location); | 450 __ lw(a0, unmapped_location); |
| 451 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); | 451 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); |
| 452 __ Branch(&slow, eq, a0, Operand(a3)); | 452 __ Branch(&slow, eq, a0, Operand(a3)); |
| 453 __ Ret(USE_DELAY_SLOT); | 453 __ Ret(USE_DELAY_SLOT); |
| 454 __ mov(v0, a0); | 454 __ mov(v0, a0); |
| 455 __ bind(&slow); | 455 __ bind(&slow); |
| 456 GenerateMiss(masm); | 456 GenerateMiss(masm); |
| 457 } | 457 } |
| 458 | 458 |
| 459 | 459 |
| 460 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 460 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 461 Register receiver = ReceiverRegister(); | 461 Register receiver = ReceiverRegister(); |
| 462 Register key = NameRegister(); | 462 Register key = NameRegister(); |
| 463 Register value = ValueRegister(); | 463 Register value = ValueRegister(); |
| 464 ASSERT(value.is(a0)); | 464 DCHECK(value.is(a0)); |
| 465 | 465 |
| 466 Label slow, notin; | 466 Label slow, notin; |
| 467 // Store address is returned in register (of MemOperand) mapped_location. | 467 // Store address is returned in register (of MemOperand) mapped_location. |
| 468 MemOperand mapped_location = GenerateMappedArgumentsLookup( | 468 MemOperand mapped_location = GenerateMappedArgumentsLookup( |
| 469 masm, receiver, key, a3, t0, t1, ¬in, &slow); | 469 masm, receiver, key, a3, t0, t1, ¬in, &slow); |
| 470 __ sw(value, mapped_location); | 470 __ sw(value, mapped_location); |
| 471 __ mov(t5, value); | 471 __ mov(t5, value); |
| 472 ASSERT_EQ(mapped_location.offset(), 0); | 472 DCHECK_EQ(mapped_location.offset(), 0); |
| 473 __ RecordWrite(a3, mapped_location.rm(), t5, | 473 __ RecordWrite(a3, mapped_location.rm(), t5, |
| 474 kRAHasNotBeenSaved, kDontSaveFPRegs); | 474 kRAHasNotBeenSaved, kDontSaveFPRegs); |
| 475 __ Ret(USE_DELAY_SLOT); | 475 __ Ret(USE_DELAY_SLOT); |
| 476 __ mov(v0, value); // (In delay slot) return the value stored in v0. | 476 __ mov(v0, value); // (In delay slot) return the value stored in v0. |
| 477 __ bind(¬in); | 477 __ bind(¬in); |
| 478 // The unmapped lookup expects that the parameter map is in a3. | 478 // The unmapped lookup expects that the parameter map is in a3. |
| 479 // Store address is returned in register (of MemOperand) unmapped_location. | 479 // Store address is returned in register (of MemOperand) unmapped_location. |
| 480 MemOperand unmapped_location = | 480 MemOperand unmapped_location = |
| 481 GenerateUnmappedArgumentsLookup(masm, key, a3, t0, &slow); | 481 GenerateUnmappedArgumentsLookup(masm, key, a3, t0, &slow); |
| 482 __ sw(value, unmapped_location); | 482 __ sw(value, unmapped_location); |
| 483 __ mov(t5, value); | 483 __ mov(t5, value); |
| 484 ASSERT_EQ(unmapped_location.offset(), 0); | 484 DCHECK_EQ(unmapped_location.offset(), 0); |
| 485 __ RecordWrite(a3, unmapped_location.rm(), t5, | 485 __ RecordWrite(a3, unmapped_location.rm(), t5, |
| 486 kRAHasNotBeenSaved, kDontSaveFPRegs); | 486 kRAHasNotBeenSaved, kDontSaveFPRegs); |
| 487 __ Ret(USE_DELAY_SLOT); | 487 __ Ret(USE_DELAY_SLOT); |
| 488 __ mov(v0, a0); // (In delay slot) return the value stored in v0. | 488 __ mov(v0, a0); // (In delay slot) return the value stored in v0. |
| 489 __ bind(&slow); | 489 __ bind(&slow); |
| 490 GenerateMiss(masm); | 490 GenerateMiss(masm); |
| 491 } | 491 } |
| 492 | 492 |
| 493 | 493 |
| 494 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 494 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 506 __ TailCallExternalReference(ref, 2, 1); | 506 __ TailCallExternalReference(ref, 2, 1); |
| 507 } | 507 } |
| 508 | 508 |
| 509 | 509 |
| 510 // IC register specifications | 510 // IC register specifications |
| 511 const Register LoadIC::ReceiverRegister() { return a1; } | 511 const Register LoadIC::ReceiverRegister() { return a1; } |
| 512 const Register LoadIC::NameRegister() { return a2; } | 512 const Register LoadIC::NameRegister() { return a2; } |
| 513 | 513 |
| 514 | 514 |
| 515 const Register LoadIC::SlotRegister() { | 515 const Register LoadIC::SlotRegister() { |
| 516 ASSERT(FLAG_vector_ics); | 516 DCHECK(FLAG_vector_ics); |
| 517 return a0; | 517 return a0; |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 const Register LoadIC::VectorRegister() { | 521 const Register LoadIC::VectorRegister() { |
| 522 ASSERT(FLAG_vector_ics); | 522 DCHECK(FLAG_vector_ics); |
| 523 return a3; | 523 return a3; |
| 524 } | 524 } |
| 525 | 525 |
| 526 | 526 |
| 527 const Register StoreIC::ReceiverRegister() { return a1; } | 527 const Register StoreIC::ReceiverRegister() { return a1; } |
| 528 const Register StoreIC::NameRegister() { return a2; } | 528 const Register StoreIC::NameRegister() { return a2; } |
| 529 const Register StoreIC::ValueRegister() { return a0; } | 529 const Register StoreIC::ValueRegister() { return a0; } |
| 530 | 530 |
| 531 | 531 |
| 532 const Register KeyedStoreIC::MapRegister() { | 532 const Register KeyedStoreIC::MapRegister() { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 543 } | 543 } |
| 544 | 544 |
| 545 | 545 |
| 546 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 546 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 547 // The return address is in ra. | 547 // The return address is in ra. |
| 548 Label slow, check_name, index_smi, index_name, property_array_property; | 548 Label slow, check_name, index_smi, index_name, property_array_property; |
| 549 Label probe_dictionary, check_number_dictionary; | 549 Label probe_dictionary, check_number_dictionary; |
| 550 | 550 |
| 551 Register key = NameRegister(); | 551 Register key = NameRegister(); |
| 552 Register receiver = ReceiverRegister(); | 552 Register receiver = ReceiverRegister(); |
| 553 ASSERT(key.is(a2)); | 553 DCHECK(key.is(a2)); |
| 554 ASSERT(receiver.is(a1)); | 554 DCHECK(receiver.is(a1)); |
| 555 | 555 |
| 556 Isolate* isolate = masm->isolate(); | 556 Isolate* isolate = masm->isolate(); |
| 557 | 557 |
| 558 // Check that the key is a smi. | 558 // Check that the key is a smi. |
| 559 __ JumpIfNotSmi(key, &check_name); | 559 __ JumpIfNotSmi(key, &check_name); |
| 560 __ bind(&index_smi); | 560 __ bind(&index_smi); |
| 561 // Now the key is known to be a smi. This place is also jumped to from below | 561 // Now the key is known to be a smi. This place is also jumped to from below |
| 562 // where a numeric string is converted to a smi. | 562 // where a numeric string is converted to a smi. |
| 563 | 563 |
| 564 GenerateKeyedLoadReceiverCheck( | 564 GenerateKeyedLoadReceiverCheck( |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 | 714 |
| 715 | 715 |
| 716 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 716 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 717 // Return address is in ra. | 717 // Return address is in ra. |
| 718 Label miss; | 718 Label miss; |
| 719 | 719 |
| 720 Register receiver = ReceiverRegister(); | 720 Register receiver = ReceiverRegister(); |
| 721 Register index = NameRegister(); | 721 Register index = NameRegister(); |
| 722 Register scratch = a3; | 722 Register scratch = a3; |
| 723 Register result = v0; | 723 Register result = v0; |
| 724 ASSERT(!scratch.is(receiver) && !scratch.is(index)); | 724 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 725 | 725 |
| 726 StringCharAtGenerator char_at_generator(receiver, | 726 StringCharAtGenerator char_at_generator(receiver, |
| 727 index, | 727 index, |
| 728 scratch, | 728 scratch, |
| 729 result, | 729 result, |
| 730 &miss, // When not a string. | 730 &miss, // When not a string. |
| 731 &miss, // When not a number. | 731 &miss, // When not a number. |
| 732 &miss, // When index out of range. | 732 &miss, // When index out of range. |
| 733 STRING_INDEX_IS_ARRAY_INDEX); | 733 STRING_INDEX_IS_ARRAY_INDEX); |
| 734 char_at_generator.GenerateFast(masm); | 734 char_at_generator.GenerateFast(masm); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 // -- ra : return address | 934 // -- ra : return address |
| 935 // ----------------------------------- | 935 // ----------------------------------- |
| 936 Label slow, fast_object, fast_object_grow; | 936 Label slow, fast_object, fast_object_grow; |
| 937 Label fast_double, fast_double_grow; | 937 Label fast_double, fast_double_grow; |
| 938 Label array, extra, check_if_double_array; | 938 Label array, extra, check_if_double_array; |
| 939 | 939 |
| 940 // Register usage. | 940 // Register usage. |
| 941 Register value = ValueRegister(); | 941 Register value = ValueRegister(); |
| 942 Register key = NameRegister(); | 942 Register key = NameRegister(); |
| 943 Register receiver = ReceiverRegister(); | 943 Register receiver = ReceiverRegister(); |
| 944 ASSERT(value.is(a0)); | 944 DCHECK(value.is(a0)); |
| 945 Register receiver_map = a3; | 945 Register receiver_map = a3; |
| 946 Register elements_map = t2; | 946 Register elements_map = t2; |
| 947 Register elements = t3; // Elements array of the receiver. | 947 Register elements = t3; // Elements array of the receiver. |
| 948 // t0 and t1 are used as general scratch registers. | 948 // t0 and t1 are used as general scratch registers. |
| 949 | 949 |
| 950 // Check that the key is a smi. | 950 // Check that the key is a smi. |
| 951 __ JumpIfNotSmi(key, &slow); | 951 __ JumpIfNotSmi(key, &slow); |
| 952 // Check that the object isn't a smi. | 952 // Check that the object isn't a smi. |
| 953 __ JumpIfSmi(receiver, &slow); | 953 __ JumpIfSmi(receiver, &slow); |
| 954 // Get the map of the object. | 954 // Get the map of the object. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 | 1022 |
| 1023 | 1023 |
| 1024 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 1024 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 1025 // Return address is in ra. | 1025 // Return address is in ra. |
| 1026 Label slow; | 1026 Label slow; |
| 1027 | 1027 |
| 1028 Register receiver = ReceiverRegister(); | 1028 Register receiver = ReceiverRegister(); |
| 1029 Register key = NameRegister(); | 1029 Register key = NameRegister(); |
| 1030 Register scratch1 = a3; | 1030 Register scratch1 = a3; |
| 1031 Register scratch2 = t0; | 1031 Register scratch2 = t0; |
| 1032 ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); | 1032 DCHECK(!scratch1.is(receiver) && !scratch1.is(key)); |
| 1033 ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); | 1033 DCHECK(!scratch2.is(receiver) && !scratch2.is(key)); |
| 1034 | 1034 |
| 1035 // Check that the receiver isn't a smi. | 1035 // Check that the receiver isn't a smi. |
| 1036 __ JumpIfSmi(receiver, &slow); | 1036 __ JumpIfSmi(receiver, &slow); |
| 1037 | 1037 |
| 1038 // Check that the key is an array index, that is Uint32. | 1038 // Check that the key is an array index, that is Uint32. |
| 1039 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); | 1039 __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); |
| 1040 __ Branch(&slow, ne, t0, Operand(zero_reg)); | 1040 __ Branch(&slow, ne, t0, Operand(zero_reg)); |
| 1041 | 1041 |
| 1042 // Get the map of the receiver. | 1042 // Get the map of the receiver. |
| 1043 __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1043 __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 ExternalReference ref = | 1091 ExternalReference ref = |
| 1092 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 1092 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); |
| 1093 | 1093 |
| 1094 __ TailCallExternalReference(ref, 3, 1); | 1094 __ TailCallExternalReference(ref, 3, 1); |
| 1095 } | 1095 } |
| 1096 | 1096 |
| 1097 | 1097 |
| 1098 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1098 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 1099 Register receiver = ReceiverRegister(); | 1099 Register receiver = ReceiverRegister(); |
| 1100 Register name = NameRegister(); | 1100 Register name = NameRegister(); |
| 1101 ASSERT(receiver.is(a1)); | 1101 DCHECK(receiver.is(a1)); |
| 1102 ASSERT(name.is(a2)); | 1102 DCHECK(name.is(a2)); |
| 1103 ASSERT(ValueRegister().is(a0)); | 1103 DCHECK(ValueRegister().is(a0)); |
| 1104 | 1104 |
| 1105 // Get the receiver from the stack and probe the stub cache. | 1105 // Get the receiver from the stack and probe the stub cache. |
| 1106 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 1106 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 1107 Code::ComputeHandlerFlags(Code::STORE_IC)); | 1107 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 1108 masm->isolate()->stub_cache()->GenerateProbe( | 1108 masm->isolate()->stub_cache()->GenerateProbe( |
| 1109 masm, flags, receiver, name, a3, t0, t1, t2); | 1109 masm, flags, receiver, name, a3, t0, t1, t2); |
| 1110 | 1110 |
| 1111 // Cache miss: Jump to runtime. | 1111 // Cache miss: Jump to runtime. |
| 1112 GenerateMiss(masm); | 1112 GenerateMiss(masm); |
| 1113 } | 1113 } |
| 1114 | 1114 |
| 1115 | 1115 |
| 1116 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1116 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| 1117 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); | 1117 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 1118 // Perform tail call to the entry. | 1118 // Perform tail call to the entry. |
| 1119 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), | 1119 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), |
| 1120 masm->isolate()); | 1120 masm->isolate()); |
| 1121 __ TailCallExternalReference(ref, 3, 1); | 1121 __ TailCallExternalReference(ref, 3, 1); |
| 1122 } | 1122 } |
| 1123 | 1123 |
| 1124 | 1124 |
| 1125 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1125 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 1126 Label miss; | 1126 Label miss; |
| 1127 Register receiver = ReceiverRegister(); | 1127 Register receiver = ReceiverRegister(); |
| 1128 Register name = NameRegister(); | 1128 Register name = NameRegister(); |
| 1129 Register value = ValueRegister(); | 1129 Register value = ValueRegister(); |
| 1130 Register dictionary = a3; | 1130 Register dictionary = a3; |
| 1131 ASSERT(receiver.is(a1)); | 1131 DCHECK(receiver.is(a1)); |
| 1132 ASSERT(name.is(a2)); | 1132 DCHECK(name.is(a2)); |
| 1133 ASSERT(value.is(a0)); | 1133 DCHECK(value.is(a0)); |
| 1134 | 1134 |
| 1135 __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 1135 __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 1136 | 1136 |
| 1137 GenerateDictionaryStore(masm, &miss, dictionary, name, value, t0, t1); | 1137 GenerateDictionaryStore(masm, &miss, dictionary, name, value, t0, t1); |
| 1138 Counters* counters = masm->isolate()->counters(); | 1138 Counters* counters = masm->isolate()->counters(); |
| 1139 __ IncrementCounter(counters->store_normal_hit(), 1, t0, t1); | 1139 __ IncrementCounter(counters->store_normal_hit(), 1, t0, t1); |
| 1140 __ Ret(); | 1140 __ Ret(); |
| 1141 | 1141 |
| 1142 __ bind(&miss); | 1142 __ bind(&miss); |
| 1143 __ IncrementCounter(counters->store_normal_miss(), 1, t0, t1); | 1143 __ IncrementCounter(counters->store_normal_miss(), 1, t0, t1); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 // Enabling by changing from | 1229 // Enabling by changing from |
| 1230 // andi at, rx, 0 | 1230 // andi at, rx, 0 |
| 1231 // Branch <target>, eq, at, Operand(zero_reg) | 1231 // Branch <target>, eq, at, Operand(zero_reg) |
| 1232 // to: | 1232 // to: |
| 1233 // andi at, rx, #kSmiTagMask | 1233 // andi at, rx, #kSmiTagMask |
| 1234 // Branch <target>, ne, at, Operand(zero_reg) | 1234 // Branch <target>, ne, at, Operand(zero_reg) |
| 1235 // and vice-versa to be disabled again. | 1235 // and vice-versa to be disabled again. |
| 1236 CodePatcher patcher(patch_address, 2); | 1236 CodePatcher patcher(patch_address, 2); |
| 1237 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); | 1237 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); |
| 1238 if (check == ENABLE_INLINED_SMI_CHECK) { | 1238 if (check == ENABLE_INLINED_SMI_CHECK) { |
| 1239 ASSERT(Assembler::IsAndImmediate(instr_at_patch)); | 1239 DCHECK(Assembler::IsAndImmediate(instr_at_patch)); |
| 1240 ASSERT_EQ(0, Assembler::GetImmediate16(instr_at_patch)); | 1240 DCHECK_EQ(0, Assembler::GetImmediate16(instr_at_patch)); |
| 1241 patcher.masm()->andi(at, reg, kSmiTagMask); | 1241 patcher.masm()->andi(at, reg, kSmiTagMask); |
| 1242 } else { | 1242 } else { |
| 1243 ASSERT(check == DISABLE_INLINED_SMI_CHECK); | 1243 DCHECK(check == DISABLE_INLINED_SMI_CHECK); |
| 1244 ASSERT(Assembler::IsAndImmediate(instr_at_patch)); | 1244 DCHECK(Assembler::IsAndImmediate(instr_at_patch)); |
| 1245 patcher.masm()->andi(at, reg, 0); | 1245 patcher.masm()->andi(at, reg, 0); |
| 1246 } | 1246 } |
| 1247 ASSERT(Assembler::IsBranch(branch_instr)); | 1247 DCHECK(Assembler::IsBranch(branch_instr)); |
| 1248 if (Assembler::IsBeq(branch_instr)) { | 1248 if (Assembler::IsBeq(branch_instr)) { |
| 1249 patcher.ChangeBranchCondition(ne); | 1249 patcher.ChangeBranchCondition(ne); |
| 1250 } else { | 1250 } else { |
| 1251 ASSERT(Assembler::IsBne(branch_instr)); | 1251 DCHECK(Assembler::IsBne(branch_instr)); |
| 1252 patcher.ChangeBranchCondition(eq); | 1252 patcher.ChangeBranchCondition(eq); |
| 1253 } | 1253 } |
| 1254 } | 1254 } |
| 1255 | 1255 |
| 1256 | 1256 |
| 1257 } } // namespace v8::internal | 1257 } } // namespace v8::internal |
| 1258 | 1258 |
| 1259 #endif // V8_TARGET_ARCH_MIPS | 1259 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |