462
462
__ movl(rdi, FieldOperand(rax, String::kHashFieldOffset));
463
463
__ shr(rdi, Immediate(String::kHashShift));
464
464
__ xor_(rcx, rdi);
465
__ and_(rcx, Immediate(KeyedLookupCache::kCapacityMask));
465
int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
466
__ and_(rcx, Immediate(mask));
467
468
// Load the key (consisting of map and symbol) from the cache and
468
469
// check for match.
470
Label load_in_object_property;
471
static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
472
Label hit_on_nth_entry[kEntriesPerBucket];
469
473
ExternalReference cache_keys
470
474
= ExternalReference::keyed_lookup_cache_keys(masm->isolate());
472
__ shl(rdi, Immediate(kPointerSizeLog2 + 1));
473
__ LoadAddress(kScratchRegister, cache_keys);
474
__ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, 0));
476
for (int i = 0; i < kEntriesPerBucket - 1; i++) {
477
Label try_next_entry;
479
__ shl(rdi, Immediate(kPointerSizeLog2 + 1));
480
__ LoadAddress(kScratchRegister, cache_keys);
481
int off = kPointerSize * i * 2;
482
__ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, off));
483
__ j(not_equal, &try_next_entry);
484
__ cmpq(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
485
__ j(equal, &hit_on_nth_entry[i]);
486
__ bind(&try_next_entry);
489
int off = kPointerSize * (kEntriesPerBucket - 1) * 2;
490
__ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, off));
475
491
__ j(not_equal, &slow);
476
__ cmpq(rax, Operand(kScratchRegister, rdi, times_1, kPointerSize));
492
__ cmpq(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
477
493
__ j(not_equal, &slow);
479
495
// Get field offset, which is a 32-bit integer.
480
496
ExternalReference cache_field_offsets
481
497
= ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
482
__ LoadAddress(kScratchRegister, cache_field_offsets);
483
__ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
484
__ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
486
__ j(above_equal, &property_array_property);
500
for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
501
__ bind(&hit_on_nth_entry[i]);
503
__ addl(rcx, Immediate(i));
505
__ LoadAddress(kScratchRegister, cache_field_offsets);
506
__ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
507
__ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
509
__ j(above_equal, &property_array_property);
511
__ jmp(&load_in_object_property);
488
515
// Load in-object property.
516
__ bind(&load_in_object_property);
489
517
__ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
490
518
__ addq(rcx, rdi);
491
519
__ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
1397
1425
// -- rsp[0] : return address
1398
1426
// -----------------------------------
1400
// This accepts as a receiver anything JSObject::SetElementsLength accepts
1401
// (currently anything except for external and pixel arrays which means
1402
// anything with elements of FixedArray type.), but currently is restricted
1404
// Value must be a number, but only smis are accepted as the most common case.
1428
// This accepts as a receiver anything JSArray::SetElementsLength accepts
1429
// (currently anything except for external arrays which means anything with
1430
// elements of FixedArray type). Value must be a number, but only smis are
1431
// accepted as the most common case.
1423
1450
__ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch);
1424
1451
__ j(not_equal, &miss);
1453
// Check that the array has fast properties, otherwise the length
1454
// property might have been redefined.
1455
__ movq(scratch, FieldOperand(receiver, JSArray::kPropertiesOffset));
1456
__ CompareRoot(FieldOperand(scratch, FixedArray::kMapOffset),
1457
Heap::kHashTableMapRootIndex);
1426
1460
// Check that value is a smi.
1427
1461
__ JumpIfNotSmi(value, &miss);