OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 6523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6534 // Do a tail call to the rewritten stub. | 6534 // Do a tail call to the rewritten stub. |
6535 __ jmp(edi); | 6535 __ jmp(edi); |
6536 } | 6536 } |
6537 | 6537 |
6538 | 6538 |
6539 // Helper function used to check that the dictionary doesn't contain | 6539 // Helper function used to check that the dictionary doesn't contain |
6540 // the property. This function may return false negatives, so miss_label | 6540 // the property. This function may return false negatives, so miss_label |
6541 // must always call a backup property check that is complete. | 6541 // must always call a backup property check that is complete. |
6542 // This function is safe to call if the receiver has fast properties. | 6542 // This function is safe to call if the receiver has fast properties. |
6543 // Name must be a symbol and receiver must be a heap object. | 6543 // Name must be a symbol and receiver must be a heap object. |
6544 MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup( | 6544 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, |
| 6545 Label* miss, |
| 6546 Label* done, |
| 6547 Register properties, |
| 6548 Handle<String> name, |
| 6549 Register r0) { |
| 6550 ASSERT(name->IsSymbol()); |
| 6551 |
| 6552 // If names of slots in range from 1 to kProbes - 1 for the hash value are |
| 6553 // not equal to the name and kProbes-th slot is not used (its name is the |
| 6554 // undefined value), it guarantees the hash table doesn't contain the |
| 6555 // property. It's true even if some slots represent deleted properties |
| 6556 // (their names are the null value). |
| 6557 for (int i = 0; i < kInlinedProbes; i++) { |
| 6558 // Compute the masked index: (hash + i + i * i) & mask. |
| 6559 Register index = r0; |
| 6560 // Capacity is smi 2^n. |
| 6561 __ mov(index, FieldOperand(properties, kCapacityOffset)); |
| 6562 __ dec(index); |
| 6563 __ and_(index, |
| 6564 Immediate(Smi::FromInt(name->Hash() + |
| 6565 StringDictionary::GetProbeOffset(i)))); |
| 6566 |
| 6567 // Scale the index by multiplying by the entry size. |
| 6568 ASSERT(StringDictionary::kEntrySize == 3); |
| 6569 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. |
| 6570 Register entity_name = r0; |
| 6571 // Having undefined at this place means the name is not contained. |
| 6572 ASSERT_EQ(kSmiTagSize, 1); |
| 6573 __ mov(entity_name, Operand(properties, index, times_half_pointer_size, |
| 6574 kElementsStartOffset - kHeapObjectTag)); |
| 6575 __ cmp(entity_name, masm->isolate()->factory()->undefined_value()); |
| 6576 __ j(equal, done); |
| 6577 |
| 6578 // Stop if found the property. |
| 6579 __ cmp(entity_name, Handle<String>(name)); |
| 6580 __ j(equal, miss); |
| 6581 |
| 6582 // Check if the entry name is not a symbol. |
| 6583 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); |
| 6584 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), |
| 6585 kIsSymbolMask); |
| 6586 __ j(zero, miss); |
| 6587 } |
| 6588 |
| 6589 StringDictionaryLookupStub stub(properties, |
| 6590 r0, |
| 6591 r0, |
| 6592 StringDictionaryLookupStub::NEGATIVE_LOOKUP); |
| 6593 __ push(Immediate(Handle<Object>(name))); |
| 6594 __ push(Immediate(name->Hash())); |
| 6595 __ CallStub(&stub); |
| 6596 __ test(r0, r0); |
| 6597 __ j(not_zero, miss); |
| 6598 __ jmp(done); |
| 6599 } |
| 6600 |
| 6601 |
| 6602 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 6603 // handlified. |
| 6604 MaybeObject* StringDictionaryLookupStub::TryGenerateNegativeLookup( |
6545 MacroAssembler* masm, | 6605 MacroAssembler* masm, |
6546 Label* miss, | 6606 Label* miss, |
6547 Label* done, | 6607 Label* done, |
6548 Register properties, | 6608 Register properties, |
6549 String* name, | 6609 String* name, |
6550 Register r0) { | 6610 Register r0) { |
6551 ASSERT(name->IsSymbol()); | 6611 ASSERT(name->IsSymbol()); |
6552 | 6612 |
6553 // If names of slots in range from 1 to kProbes - 1 for the hash value are | 6613 // If names of slots in range from 1 to kProbes - 1 for the hash value are |
6554 // not equal to the name and kProbes-th slot is not used (its name is the | 6614 // not equal to the name and kProbes-th slot is not used (its name is the |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7022 __ bind(&need_incremental); | 7082 __ bind(&need_incremental); |
7023 | 7083 |
7024 // Fall through when we need to inform the incremental marker. | 7084 // Fall through when we need to inform the incremental marker. |
7025 } | 7085 } |
7026 | 7086 |
7027 #undef __ | 7087 #undef __ |
7028 | 7088 |
7029 } } // namespace v8::internal | 7089 } } // namespace v8::internal |
7030 | 7090 |
7031 #endif // V8_TARGET_ARCH_IA32 | 7091 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |