OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 } | 279 } |
280 | 280 |
281 | 281 |
282 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 282 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
283 // The return address is in lr. | 283 // The return address is in lr. |
284 Isolate* isolate = masm->isolate(); | 284 Isolate* isolate = masm->isolate(); |
285 ASM_LOCATION("LoadIC::GenerateMiss"); | 285 ASM_LOCATION("LoadIC::GenerateMiss"); |
286 | 286 |
287 DCHECK(!AreAliased(x4, x5, LoadWithVectorDescriptor::SlotRegister(), | 287 DCHECK(!AreAliased(x4, x5, LoadWithVectorDescriptor::SlotRegister(), |
288 LoadWithVectorDescriptor::VectorRegister())); | 288 LoadWithVectorDescriptor::VectorRegister())); |
289 __ IncrementCounter(isolate->counters()->load_miss(), 1, x4, x5); | 289 __ IncrementCounter(isolate->counters()->ic_load_miss(), 1, x4, x5); |
290 | 290 |
291 // Perform tail call to the entry. | 291 // Perform tail call to the entry. |
292 __ Push(LoadWithVectorDescriptor::ReceiverRegister(), | 292 __ Push(LoadWithVectorDescriptor::ReceiverRegister(), |
293 LoadWithVectorDescriptor::NameRegister(), | 293 LoadWithVectorDescriptor::NameRegister(), |
294 LoadWithVectorDescriptor::SlotRegister(), | 294 LoadWithVectorDescriptor::SlotRegister(), |
295 LoadWithVectorDescriptor::VectorRegister()); | 295 LoadWithVectorDescriptor::VectorRegister()); |
296 __ TailCallRuntime(Runtime::kLoadIC_Miss); | 296 __ TailCallRuntime(Runtime::kLoadIC_Miss); |
297 } | 297 } |
298 | 298 |
299 | 299 |
300 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm, | 300 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm, |
301 LanguageMode language_mode) { | 301 LanguageMode language_mode) { |
302 // The return address is in lr. | 302 // The return address is in lr. |
303 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | 303 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); |
304 | 304 |
305 // Do tail-call to runtime routine. | 305 // Do tail-call to runtime routine. |
306 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kGetPropertyStrong | 306 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kGetPropertyStrong |
307 : Runtime::kGetProperty); | 307 : Runtime::kGetProperty); |
308 } | 308 } |
309 | 309 |
310 | 310 |
311 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 311 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
312 // The return address is in lr. | 312 // The return address is in lr. |
313 Isolate* isolate = masm->isolate(); | 313 Isolate* isolate = masm->isolate(); |
314 | 314 |
315 DCHECK(!AreAliased(x10, x11, LoadWithVectorDescriptor::SlotRegister(), | 315 DCHECK(!AreAliased(x10, x11, LoadWithVectorDescriptor::SlotRegister(), |
316 LoadWithVectorDescriptor::VectorRegister())); | 316 LoadWithVectorDescriptor::VectorRegister())); |
317 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); | 317 __ IncrementCounter(isolate->counters()->ic_keyed_load_miss(), 1, x10, x11); |
318 | 318 |
319 __ Push(LoadWithVectorDescriptor::ReceiverRegister(), | 319 __ Push(LoadWithVectorDescriptor::ReceiverRegister(), |
320 LoadWithVectorDescriptor::NameRegister(), | 320 LoadWithVectorDescriptor::NameRegister(), |
321 LoadWithVectorDescriptor::SlotRegister(), | 321 LoadWithVectorDescriptor::SlotRegister(), |
322 LoadWithVectorDescriptor::VectorRegister()); | 322 LoadWithVectorDescriptor::VectorRegister()); |
323 | 323 |
324 // Perform tail call to the entry. | 324 // Perform tail call to the entry. |
325 __ TailCallRuntime(Runtime::kKeyedLoadIC_Miss); | 325 __ TailCallRuntime(Runtime::kKeyedLoadIC_Miss); |
326 } | 326 } |
327 | 327 |
(...skipping 24 matching lines...) Expand all Loading... |
352 Register result = x0; | 352 Register result = x0; |
353 | 353 |
354 GenerateKeyedLoadReceiverCheck(masm, receiver, scratch1, scratch2, | 354 GenerateKeyedLoadReceiverCheck(masm, receiver, scratch1, scratch2, |
355 Map::kHasIndexedInterceptor, slow); | 355 Map::kHasIndexedInterceptor, slow); |
356 | 356 |
357 // Check the receiver's map to see if it has fast elements. | 357 // Check the receiver's map to see if it has fast elements. |
358 __ CheckFastElements(scratch1, scratch2, &check_number_dictionary); | 358 __ CheckFastElements(scratch1, scratch2, &check_number_dictionary); |
359 | 359 |
360 GenerateFastArrayLoad(masm, receiver, key, scratch3, scratch2, scratch1, | 360 GenerateFastArrayLoad(masm, receiver, key, scratch3, scratch2, scratch1, |
361 result, slow, language_mode); | 361 result, slow, language_mode); |
362 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, | 362 __ IncrementCounter(isolate->counters()->ic_keyed_load_generic_smi(), 1, |
363 scratch1, scratch2); | 363 scratch1, scratch2); |
364 __ Ret(); | 364 __ Ret(); |
365 | 365 |
366 __ Bind(&check_number_dictionary); | 366 __ Bind(&check_number_dictionary); |
367 __ Ldr(scratch3, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 367 __ Ldr(scratch3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
368 __ Ldr(scratch2, FieldMemOperand(scratch3, JSObject::kMapOffset)); | 368 __ Ldr(scratch2, FieldMemOperand(scratch3, JSObject::kMapOffset)); |
369 | 369 |
370 // Check whether we have a number dictionary. | 370 // Check whether we have a number dictionary. |
371 __ JumpIfNotRoot(scratch2, Heap::kHashTableMapRootIndex, slow); | 371 __ JumpIfNotRoot(scratch2, Heap::kHashTableMapRootIndex, slow); |
372 | 372 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 // Cache miss. | 417 // Cache miss. |
418 KeyedLoadIC::GenerateMiss(masm); | 418 KeyedLoadIC::GenerateMiss(masm); |
419 | 419 |
420 // Do a quick inline probe of the receiver's dictionary, if it exists. | 420 // Do a quick inline probe of the receiver's dictionary, if it exists. |
421 __ Bind(&probe_dictionary); | 421 __ Bind(&probe_dictionary); |
422 __ Ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 422 __ Ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
423 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 423 __ Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
424 GenerateGlobalInstanceTypeCheck(masm, scratch1, slow); | 424 GenerateGlobalInstanceTypeCheck(masm, scratch1, slow); |
425 // Load the property. | 425 // Load the property. |
426 GenerateDictionaryLoad(masm, slow, scratch2, key, result, scratch1, scratch3); | 426 GenerateDictionaryLoad(masm, slow, scratch2, key, result, scratch1, scratch3); |
427 __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1, | 427 __ IncrementCounter(isolate->counters()->ic_keyed_load_generic_symbol(), 1, |
428 scratch1, scratch2); | 428 scratch1, scratch2); |
429 __ Ret(); | 429 __ Ret(); |
430 } | 430 } |
431 | 431 |
432 | 432 |
433 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm, | 433 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm, |
434 LanguageMode language_mode) { | 434 LanguageMode language_mode) { |
435 // The return address is in lr. | 435 // The return address is in lr. |
436 Label slow, check_name, index_smi, index_name; | 436 Label slow, check_name, index_smi, index_name; |
437 | 437 |
438 Register key = LoadDescriptor::NameRegister(); | 438 Register key = LoadDescriptor::NameRegister(); |
439 Register receiver = LoadDescriptor::ReceiverRegister(); | 439 Register receiver = LoadDescriptor::ReceiverRegister(); |
440 DCHECK(key.is(x2)); | 440 DCHECK(key.is(x2)); |
441 DCHECK(receiver.is(x1)); | 441 DCHECK(receiver.is(x1)); |
442 | 442 |
443 __ JumpIfNotSmi(key, &check_name); | 443 __ JumpIfNotSmi(key, &check_name); |
444 __ Bind(&index_smi); | 444 __ Bind(&index_smi); |
445 // Now the key is known to be a smi. This place is also jumped to from below | 445 // Now the key is known to be a smi. This place is also jumped to from below |
446 // where a numeric string is converted to a smi. | 446 // where a numeric string is converted to a smi. |
447 GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow, | 447 GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow, |
448 language_mode); | 448 language_mode); |
449 | 449 |
450 // Slow case. | 450 // Slow case. |
451 __ Bind(&slow); | 451 __ Bind(&slow); |
452 __ IncrementCounter(masm->isolate()->counters()->keyed_load_generic_slow(), 1, | 452 __ IncrementCounter(masm->isolate()->counters()->ic_keyed_load_generic_slow(), |
453 x4, x3); | 453 1, x4, x3); |
454 GenerateRuntimeGetProperty(masm, language_mode); | 454 GenerateRuntimeGetProperty(masm, language_mode); |
455 | 455 |
456 __ Bind(&check_name); | 456 __ Bind(&check_name); |
457 GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow); | 457 GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow); |
458 | 458 |
459 GenerateKeyedLoadWithNameKey(masm, key, receiver, x4, x5, x6, x7, x3, &slow); | 459 GenerateKeyedLoadWithNameKey(masm, key, receiver, x4, x5, x6, x7, x3, &slow); |
460 | 460 |
461 __ Bind(&index_name); | 461 __ Bind(&index_name); |
462 __ IndexFromHash(x3, key); | 462 __ IndexFromHash(x3, key); |
463 // Now jump to the place where smi keys are handled. | 463 // Now jump to the place where smi keys are handled. |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 Register name = StoreDescriptor::NameRegister(); | 776 Register name = StoreDescriptor::NameRegister(); |
777 Register dictionary = x5; | 777 Register dictionary = x5; |
778 DCHECK(!AreAliased(value, receiver, name, | 778 DCHECK(!AreAliased(value, receiver, name, |
779 VectorStoreICDescriptor::SlotRegister(), | 779 VectorStoreICDescriptor::SlotRegister(), |
780 VectorStoreICDescriptor::VectorRegister(), x5, x6, x7)); | 780 VectorStoreICDescriptor::VectorRegister(), x5, x6, x7)); |
781 | 781 |
782 __ Ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 782 __ Ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
783 | 783 |
784 GenerateDictionaryStore(masm, &miss, dictionary, name, value, x6, x7); | 784 GenerateDictionaryStore(masm, &miss, dictionary, name, value, x6, x7); |
785 Counters* counters = masm->isolate()->counters(); | 785 Counters* counters = masm->isolate()->counters(); |
786 __ IncrementCounter(counters->store_normal_hit(), 1, x6, x7); | 786 __ IncrementCounter(counters->ic_store_normal_hit(), 1, x6, x7); |
787 __ Ret(); | 787 __ Ret(); |
788 | 788 |
789 // Cache miss: Jump to runtime. | 789 // Cache miss: Jump to runtime. |
790 __ Bind(&miss); | 790 __ Bind(&miss); |
791 __ IncrementCounter(counters->store_normal_miss(), 1, x6, x7); | 791 __ IncrementCounter(counters->ic_store_normal_miss(), 1, x6, x7); |
792 GenerateMiss(masm); | 792 GenerateMiss(masm); |
793 } | 793 } |
794 | 794 |
795 | 795 |
796 Condition CompareIC::ComputeCondition(Token::Value op) { | 796 Condition CompareIC::ComputeCondition(Token::Value op) { |
797 switch (op) { | 797 switch (op) { |
798 case Token::EQ_STRICT: | 798 case Token::EQ_STRICT: |
799 case Token::EQ: | 799 case Token::EQ: |
800 return eq; | 800 return eq; |
801 case Token::LT: | 801 case Token::LT: |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 } else { | 876 } else { |
877 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); | 877 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); |
878 // This is JumpIfSmi(smi_reg, branch_imm). | 878 // This is JumpIfSmi(smi_reg, branch_imm). |
879 patcher.tbz(smi_reg, 0, branch_imm); | 879 patcher.tbz(smi_reg, 0, branch_imm); |
880 } | 880 } |
881 } | 881 } |
882 } // namespace internal | 882 } // namespace internal |
883 } // namespace v8 | 883 } // namespace v8 |
884 | 884 |
885 #endif // V8_TARGET_ARCH_ARM64 | 885 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |