| 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_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
| 10 | 10 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 __ ld(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 165 __ ld(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, a4, a5, a6); | 289 masm, flags, receiver, name, a3, a4, a5, a6); |
| 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 Label slow; | 300 Label slow; |
| 301 | 301 |
| 302 __ ld(dictionary, | 302 __ ld(dictionary, |
| 303 FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 303 FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
| 304 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, a4); | 304 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, a4); |
| 305 __ Ret(); | 305 __ Ret(); |
| 306 | 306 |
| 307 // Dictionary load failed, go slow (but don't miss). | 307 // Dictionary load failed, go slow (but don't miss). |
| 308 __ bind(&slow); | 308 __ bind(&slow); |
| 309 GenerateRuntimeGetProperty(masm); | 309 GenerateRuntimeGetProperty(masm); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 426 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 427 __ Daddu(scratch, backing_store, scratch); | 427 __ Daddu(scratch, backing_store, scratch); |
| 428 return MemOperand(scratch); | 428 return MemOperand(scratch); |
| 429 } | 429 } |
| 430 | 430 |
| 431 | 431 |
| 432 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 432 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 433 // The return address is in ra. | 433 // The return address is in ra. |
| 434 Register receiver = ReceiverRegister(); | 434 Register receiver = ReceiverRegister(); |
| 435 Register key = NameRegister(); | 435 Register key = NameRegister(); |
| 436 ASSERT(receiver.is(a1)); | 436 DCHECK(receiver.is(a1)); |
| 437 ASSERT(key.is(a2)); | 437 DCHECK(key.is(a2)); |
| 438 | 438 |
| 439 Label slow, notin; | 439 Label slow, notin; |
| 440 MemOperand mapped_location = | 440 MemOperand mapped_location = |
| 441 GenerateMappedArgumentsLookup( | 441 GenerateMappedArgumentsLookup( |
| 442 masm, receiver, key, a0, a3, a4, ¬in, &slow); | 442 masm, receiver, key, a0, a3, a4, ¬in, &slow); |
| 443 __ Ret(USE_DELAY_SLOT); | 443 __ Ret(USE_DELAY_SLOT); |
| 444 __ ld(v0, mapped_location); | 444 __ ld(v0, mapped_location); |
| 445 __ bind(¬in); | 445 __ bind(¬in); |
| 446 // The unmapped lookup expects that the parameter map is in a2. | 446 // The unmapped lookup expects that the parameter map is in a2. |
| 447 MemOperand unmapped_location = | 447 MemOperand unmapped_location = |
| 448 GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow); | 448 GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow); |
| 449 __ ld(a0, unmapped_location); | 449 __ ld(a0, unmapped_location); |
| 450 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); | 450 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); |
| 451 __ Branch(&slow, eq, a0, Operand(a3)); | 451 __ Branch(&slow, eq, a0, Operand(a3)); |
| 452 __ Ret(USE_DELAY_SLOT); | 452 __ Ret(USE_DELAY_SLOT); |
| 453 __ mov(v0, a0); | 453 __ mov(v0, a0); |
| 454 __ bind(&slow); | 454 __ bind(&slow); |
| 455 GenerateMiss(masm); | 455 GenerateMiss(masm); |
| 456 } | 456 } |
| 457 | 457 |
| 458 | 458 |
| 459 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 459 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 460 Register receiver = ReceiverRegister(); | 460 Register receiver = ReceiverRegister(); |
| 461 Register key = NameRegister(); | 461 Register key = NameRegister(); |
| 462 Register value = ValueRegister(); | 462 Register value = ValueRegister(); |
| 463 ASSERT(value.is(a0)); | 463 DCHECK(value.is(a0)); |
| 464 | 464 |
| 465 Label slow, notin; | 465 Label slow, notin; |
| 466 // Store address is returned in register (of MemOperand) mapped_location. | 466 // Store address is returned in register (of MemOperand) mapped_location. |
| 467 MemOperand mapped_location = GenerateMappedArgumentsLookup( | 467 MemOperand mapped_location = GenerateMappedArgumentsLookup( |
| 468 masm, receiver, key, a3, a4, a5, ¬in, &slow); | 468 masm, receiver, key, a3, a4, a5, ¬in, &slow); |
| 469 __ sd(value, mapped_location); | 469 __ sd(value, mapped_location); |
| 470 __ mov(t1, value); | 470 __ mov(t1, value); |
| 471 ASSERT_EQ(mapped_location.offset(), 0); | 471 DCHECK_EQ(mapped_location.offset(), 0); |
| 472 __ RecordWrite(a3, mapped_location.rm(), t1, | 472 __ RecordWrite(a3, mapped_location.rm(), t1, |
| 473 kRAHasNotBeenSaved, kDontSaveFPRegs); | 473 kRAHasNotBeenSaved, kDontSaveFPRegs); |
| 474 __ Ret(USE_DELAY_SLOT); | 474 __ Ret(USE_DELAY_SLOT); |
| 475 __ mov(v0, value); // (In delay slot) return the value stored in v0. | 475 __ mov(v0, value); // (In delay slot) return the value stored in v0. |
| 476 __ bind(¬in); | 476 __ bind(¬in); |
| 477 // The unmapped lookup expects that the parameter map is in a3. | 477 // The unmapped lookup expects that the parameter map is in a3. |
| 478 // Store address is returned in register (of MemOperand) unmapped_location. | 478 // Store address is returned in register (of MemOperand) unmapped_location. |
| 479 MemOperand unmapped_location = | 479 MemOperand unmapped_location = |
| 480 GenerateUnmappedArgumentsLookup(masm, key, a3, a4, &slow); | 480 GenerateUnmappedArgumentsLookup(masm, key, a3, a4, &slow); |
| 481 __ sd(value, unmapped_location); | 481 __ sd(value, unmapped_location); |
| 482 __ mov(t1, value); | 482 __ mov(t1, value); |
| 483 ASSERT_EQ(unmapped_location.offset(), 0); | 483 DCHECK_EQ(unmapped_location.offset(), 0); |
| 484 __ RecordWrite(a3, unmapped_location.rm(), t1, | 484 __ RecordWrite(a3, unmapped_location.rm(), t1, |
| 485 kRAHasNotBeenSaved, kDontSaveFPRegs); | 485 kRAHasNotBeenSaved, kDontSaveFPRegs); |
| 486 __ Ret(USE_DELAY_SLOT); | 486 __ Ret(USE_DELAY_SLOT); |
| 487 __ mov(v0, a0); // (In delay slot) return the value stored in v0. | 487 __ mov(v0, a0); // (In delay slot) return the value stored in v0. |
| 488 __ bind(&slow); | 488 __ bind(&slow); |
| 489 GenerateMiss(masm); | 489 GenerateMiss(masm); |
| 490 } | 490 } |
| 491 | 491 |
| 492 | 492 |
| 493 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 493 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 505 __ TailCallExternalReference(ref, 2, 1); | 505 __ TailCallExternalReference(ref, 2, 1); |
| 506 } | 506 } |
| 507 | 507 |
| 508 | 508 |
| 509 // IC register specifications | 509 // IC register specifications |
| 510 const Register LoadIC::ReceiverRegister() { return a1; } | 510 const Register LoadIC::ReceiverRegister() { return a1; } |
| 511 const Register LoadIC::NameRegister() { return a2; } | 511 const Register LoadIC::NameRegister() { return a2; } |
| 512 | 512 |
| 513 | 513 |
| 514 const Register LoadIC::SlotRegister() { | 514 const Register LoadIC::SlotRegister() { |
| 515 ASSERT(FLAG_vector_ics); | 515 DCHECK(FLAG_vector_ics); |
| 516 return a0; | 516 return a0; |
| 517 } | 517 } |
| 518 | 518 |
| 519 | 519 |
| 520 const Register LoadIC::VectorRegister() { | 520 const Register LoadIC::VectorRegister() { |
| 521 ASSERT(FLAG_vector_ics); | 521 DCHECK(FLAG_vector_ics); |
| 522 return a3; | 522 return a3; |
| 523 } | 523 } |
| 524 | 524 |
| 525 | 525 |
| 526 const Register StoreIC::ReceiverRegister() { return a1; } | 526 const Register StoreIC::ReceiverRegister() { return a1; } |
| 527 const Register StoreIC::NameRegister() { return a2; } | 527 const Register StoreIC::NameRegister() { return a2; } |
| 528 const Register StoreIC::ValueRegister() { return a0; } | 528 const Register StoreIC::ValueRegister() { return a0; } |
| 529 | 529 |
| 530 | 530 |
| 531 const Register KeyedStoreIC::MapRegister() { | 531 const Register KeyedStoreIC::MapRegister() { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 542 } | 542 } |
| 543 | 543 |
| 544 | 544 |
| 545 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 545 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 546 // The return address is in ra. | 546 // The return address is in ra. |
| 547 Label slow, check_name, index_smi, index_name, property_array_property; | 547 Label slow, check_name, index_smi, index_name, property_array_property; |
| 548 Label probe_dictionary, check_number_dictionary; | 548 Label probe_dictionary, check_number_dictionary; |
| 549 | 549 |
| 550 Register key = NameRegister(); | 550 Register key = NameRegister(); |
| 551 Register receiver = ReceiverRegister(); | 551 Register receiver = ReceiverRegister(); |
| 552 ASSERT(key.is(a2)); | 552 DCHECK(key.is(a2)); |
| 553 ASSERT(receiver.is(a1)); | 553 DCHECK(receiver.is(a1)); |
| 554 | 554 |
| 555 Isolate* isolate = masm->isolate(); | 555 Isolate* isolate = masm->isolate(); |
| 556 | 556 |
| 557 // Check that the key is a smi. | 557 // Check that the key is a smi. |
| 558 __ JumpIfNotSmi(key, &check_name); | 558 __ JumpIfNotSmi(key, &check_name); |
| 559 __ bind(&index_smi); | 559 __ bind(&index_smi); |
| 560 // Now the key is known to be a smi. This place is also jumped to from below | 560 // Now the key is known to be a smi. This place is also jumped to from below |
| 561 // where a numeric string is converted to a smi. | 561 // where a numeric string is converted to a smi. |
| 562 | 562 |
| 563 GenerateKeyedLoadReceiverCheck( | 563 GenerateKeyedLoadReceiverCheck( |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 | 720 |
| 721 | 721 |
| 722 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 722 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 723 // Return address is in ra. | 723 // Return address is in ra. |
| 724 Label miss; | 724 Label miss; |
| 725 | 725 |
| 726 Register receiver = ReceiverRegister(); | 726 Register receiver = ReceiverRegister(); |
| 727 Register index = NameRegister(); | 727 Register index = NameRegister(); |
| 728 Register scratch = a3; | 728 Register scratch = a3; |
| 729 Register result = v0; | 729 Register result = v0; |
| 730 ASSERT(!scratch.is(receiver) && !scratch.is(index)); | 730 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 731 | 731 |
| 732 StringCharAtGenerator char_at_generator(receiver, | 732 StringCharAtGenerator char_at_generator(receiver, |
| 733 index, | 733 index, |
| 734 scratch, | 734 scratch, |
| 735 result, | 735 result, |
| 736 &miss, // When not a string. | 736 &miss, // When not a string. |
| 737 &miss, // When not a number. | 737 &miss, // When not a number. |
| 738 &miss, // When index out of range. | 738 &miss, // When index out of range. |
| 739 STRING_INDEX_IS_ARRAY_INDEX); | 739 STRING_INDEX_IS_ARRAY_INDEX); |
| 740 char_at_generator.GenerateFast(masm); | 740 char_at_generator.GenerateFast(masm); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 // -- ra : return address | 944 // -- ra : return address |
| 945 // ----------------------------------- | 945 // ----------------------------------- |
| 946 Label slow, fast_object, fast_object_grow; | 946 Label slow, fast_object, fast_object_grow; |
| 947 Label fast_double, fast_double_grow; | 947 Label fast_double, fast_double_grow; |
| 948 Label array, extra, check_if_double_array; | 948 Label array, extra, check_if_double_array; |
| 949 | 949 |
| 950 // Register usage. | 950 // Register usage. |
| 951 Register value = ValueRegister(); | 951 Register value = ValueRegister(); |
| 952 Register key = NameRegister(); | 952 Register key = NameRegister(); |
| 953 Register receiver = ReceiverRegister(); | 953 Register receiver = ReceiverRegister(); |
| 954 ASSERT(value.is(a0)); | 954 DCHECK(value.is(a0)); |
| 955 Register receiver_map = a3; | 955 Register receiver_map = a3; |
| 956 Register elements_map = a6; | 956 Register elements_map = a6; |
| 957 Register elements = a7; // Elements array of the receiver. | 957 Register elements = a7; // Elements array of the receiver. |
| 958 // a4 and a5 are used as general scratch registers. | 958 // a4 and a5 are used as general scratch registers. |
| 959 | 959 |
| 960 // Check that the key is a smi. | 960 // Check that the key is a smi. |
| 961 __ JumpIfNotSmi(key, &slow); | 961 __ JumpIfNotSmi(key, &slow); |
| 962 // Check that the object isn't a smi. | 962 // Check that the object isn't a smi. |
| 963 __ JumpIfSmi(receiver, &slow); | 963 __ JumpIfSmi(receiver, &slow); |
| 964 // Get the map of the object. | 964 // Get the map of the object. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 | 1032 |
| 1033 | 1033 |
| 1034 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 1034 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 1035 // Return address is in ra. | 1035 // Return address is in ra. |
| 1036 Label slow; | 1036 Label slow; |
| 1037 | 1037 |
| 1038 Register receiver = ReceiverRegister(); | 1038 Register receiver = ReceiverRegister(); |
| 1039 Register key = NameRegister(); | 1039 Register key = NameRegister(); |
| 1040 Register scratch1 = a3; | 1040 Register scratch1 = a3; |
| 1041 Register scratch2 = a4; | 1041 Register scratch2 = a4; |
| 1042 ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); | 1042 DCHECK(!scratch1.is(receiver) && !scratch1.is(key)); |
| 1043 ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); | 1043 DCHECK(!scratch2.is(receiver) && !scratch2.is(key)); |
| 1044 | 1044 |
| 1045 // Check that the receiver isn't a smi. | 1045 // Check that the receiver isn't a smi. |
| 1046 __ JumpIfSmi(receiver, &slow); | 1046 __ JumpIfSmi(receiver, &slow); |
| 1047 | 1047 |
| 1048 // Check that the key is an array index, that is Uint32. | 1048 // Check that the key is an array index, that is Uint32. |
| 1049 __ And(a4, key, Operand(kSmiTagMask | kSmiSignMask)); | 1049 __ And(a4, key, Operand(kSmiTagMask | kSmiSignMask)); |
| 1050 __ Branch(&slow, ne, a4, Operand(zero_reg)); | 1050 __ Branch(&slow, ne, a4, Operand(zero_reg)); |
| 1051 | 1051 |
| 1052 // Get the map of the receiver. | 1052 // Get the map of the receiver. |
| 1053 __ ld(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1053 __ ld(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 ExternalReference ref = | 1100 ExternalReference ref = |
| 1101 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 1101 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); |
| 1102 | 1102 |
| 1103 __ TailCallExternalReference(ref, 3, 1); | 1103 __ TailCallExternalReference(ref, 3, 1); |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 | 1106 |
| 1107 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1107 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 1108 Register receiver = ReceiverRegister(); | 1108 Register receiver = ReceiverRegister(); |
| 1109 Register name = NameRegister(); | 1109 Register name = NameRegister(); |
| 1110 ASSERT(receiver.is(a1)); | 1110 DCHECK(receiver.is(a1)); |
| 1111 ASSERT(name.is(a2)); | 1111 DCHECK(name.is(a2)); |
| 1112 ASSERT(ValueRegister().is(a0)); | 1112 DCHECK(ValueRegister().is(a0)); |
| 1113 | 1113 |
| 1114 // Get the receiver from the stack and probe the stub cache. | 1114 // Get the receiver from the stack and probe the stub cache. |
| 1115 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 1115 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 1116 Code::ComputeHandlerFlags(Code::STORE_IC)); | 1116 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 1117 masm->isolate()->stub_cache()->GenerateProbe( | 1117 masm->isolate()->stub_cache()->GenerateProbe( |
| 1118 masm, flags, receiver, name, a3, a4, a5, a6); | 1118 masm, flags, receiver, name, a3, a4, a5, a6); |
| 1119 | 1119 |
| 1120 // Cache miss: Jump to runtime. | 1120 // Cache miss: Jump to runtime. |
| 1121 GenerateMiss(masm); | 1121 GenerateMiss(masm); |
| 1122 } | 1122 } |
| 1123 | 1123 |
| 1124 | 1124 |
| 1125 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1125 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| 1126 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); | 1126 __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); |
| 1127 // Perform tail call to the entry. | 1127 // Perform tail call to the entry. |
| 1128 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), | 1128 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), |
| 1129 masm->isolate()); | 1129 masm->isolate()); |
| 1130 __ TailCallExternalReference(ref, 3, 1); | 1130 __ TailCallExternalReference(ref, 3, 1); |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 | 1133 |
| 1134 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1134 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 1135 Label miss; | 1135 Label miss; |
| 1136 Register receiver = ReceiverRegister(); | 1136 Register receiver = ReceiverRegister(); |
| 1137 Register name = NameRegister(); | 1137 Register name = NameRegister(); |
| 1138 Register value = ValueRegister(); | 1138 Register value = ValueRegister(); |
| 1139 Register dictionary = a3; | 1139 Register dictionary = a3; |
| 1140 ASSERT(!AreAliased(value, receiver, name, dictionary, a4, a5)); | 1140 DCHECK(!AreAliased(value, receiver, name, dictionary, a4, a5)); |
| 1141 | 1141 |
| 1142 __ ld(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 1142 __ ld(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 1143 | 1143 |
| 1144 GenerateDictionaryStore(masm, &miss, a3, name, value, a4, a5); | 1144 GenerateDictionaryStore(masm, &miss, a3, name, value, a4, a5); |
| 1145 Counters* counters = masm->isolate()->counters(); | 1145 Counters* counters = masm->isolate()->counters(); |
| 1146 __ IncrementCounter(counters->store_normal_hit(), 1, a4, a5); | 1146 __ IncrementCounter(counters->store_normal_hit(), 1, a4, a5); |
| 1147 __ Ret(); | 1147 __ Ret(); |
| 1148 | 1148 |
| 1149 __ bind(&miss); | 1149 __ bind(&miss); |
| 1150 __ IncrementCounter(counters->store_normal_miss(), 1, a4, a5); | 1150 __ IncrementCounter(counters->store_normal_miss(), 1, a4, a5); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 // Enabling by changing from | 1236 // Enabling by changing from |
| 1237 // andi at, rx, 0 | 1237 // andi at, rx, 0 |
| 1238 // Branch <target>, eq, at, Operand(zero_reg) | 1238 // Branch <target>, eq, at, Operand(zero_reg) |
| 1239 // to: | 1239 // to: |
| 1240 // andi at, rx, #kSmiTagMask | 1240 // andi at, rx, #kSmiTagMask |
| 1241 // Branch <target>, ne, at, Operand(zero_reg) | 1241 // Branch <target>, ne, at, Operand(zero_reg) |
| 1242 // and vice-versa to be disabled again. | 1242 // and vice-versa to be disabled again. |
| 1243 CodePatcher patcher(patch_address, 2); | 1243 CodePatcher patcher(patch_address, 2); |
| 1244 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); | 1244 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); |
| 1245 if (check == ENABLE_INLINED_SMI_CHECK) { | 1245 if (check == ENABLE_INLINED_SMI_CHECK) { |
| 1246 ASSERT(Assembler::IsAndImmediate(instr_at_patch)); | 1246 DCHECK(Assembler::IsAndImmediate(instr_at_patch)); |
| 1247 ASSERT_EQ(0, Assembler::GetImmediate16(instr_at_patch)); | 1247 DCHECK_EQ(0, Assembler::GetImmediate16(instr_at_patch)); |
| 1248 patcher.masm()->andi(at, reg, kSmiTagMask); | 1248 patcher.masm()->andi(at, reg, kSmiTagMask); |
| 1249 } else { | 1249 } else { |
| 1250 ASSERT(check == DISABLE_INLINED_SMI_CHECK); | 1250 DCHECK(check == DISABLE_INLINED_SMI_CHECK); |
| 1251 ASSERT(Assembler::IsAndImmediate(instr_at_patch)); | 1251 DCHECK(Assembler::IsAndImmediate(instr_at_patch)); |
| 1252 patcher.masm()->andi(at, reg, 0); | 1252 patcher.masm()->andi(at, reg, 0); |
| 1253 } | 1253 } |
| 1254 ASSERT(Assembler::IsBranch(branch_instr)); | 1254 DCHECK(Assembler::IsBranch(branch_instr)); |
| 1255 if (Assembler::IsBeq(branch_instr)) { | 1255 if (Assembler::IsBeq(branch_instr)) { |
| 1256 patcher.ChangeBranchCondition(ne); | 1256 patcher.ChangeBranchCondition(ne); |
| 1257 } else { | 1257 } else { |
| 1258 ASSERT(Assembler::IsBne(branch_instr)); | 1258 DCHECK(Assembler::IsBne(branch_instr)); |
| 1259 patcher.ChangeBranchCondition(eq); | 1259 patcher.ChangeBranchCondition(eq); |
| 1260 } | 1260 } |
| 1261 } | 1261 } |
| 1262 | 1262 |
| 1263 | 1263 |
| 1264 } } // namespace v8::internal | 1264 } } // namespace v8::internal |
| 1265 | 1265 |
| 1266 #endif // V8_TARGET_ARCH_MIPS64 | 1266 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |