Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 12330012: ES6 symbols: Allow symbols as property names (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platform ports Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 7089 matching lines...) Expand 10 before | Expand all | Expand 10 after
7100 7100
7101 // Do a tail call to the rewritten stub. 7101 // Do a tail call to the rewritten stub.
7102 __ jmp(edi); 7102 __ jmp(edi);
7103 } 7103 }
7104 7104
7105 7105
7106 // Helper function used to check that the dictionary doesn't contain 7106 // Helper function used to check that the dictionary doesn't contain
7107 // the property. This function may return false negatives, so miss_label 7107 // the property. This function may return false negatives, so miss_label
7108 // must always call a backup property check that is complete. 7108 // must always call a backup property check that is complete.
7109 // This function is safe to call if the receiver has fast properties. 7109 // This function is safe to call if the receiver has fast properties.
7110 // Name must be an internalized string and receiver must be a heap object. 7110 // Name must be a unique name and receiver must be a heap object.
7111 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, 7111 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
7112 Label* miss, 7112 Label* miss,
7113 Label* done, 7113 Label* done,
7114 Register properties, 7114 Register properties,
7115 Handle<String> name, 7115 Handle<Name> name,
7116 Register r0) { 7116 Register r0) {
7117 ASSERT(name->IsInternalizedString()); 7117 ASSERT(name->IsUniqueName());
7118 7118
7119 // If names of slots in range from 1 to kProbes - 1 for the hash value are 7119 // If names of slots in range from 1 to kProbes - 1 for the hash value are
7120 // not equal to the name and kProbes-th slot is not used (its name is the 7120 // not equal to the name and kProbes-th slot is not used (its name is the
7121 // undefined value), it guarantees the hash table doesn't contain the 7121 // undefined value), it guarantees the hash table doesn't contain the
7122 // property. It's true even if some slots represent deleted properties 7122 // property. It's true even if some slots represent deleted properties
7123 // (their names are the hole value). 7123 // (their names are the hole value).
7124 for (int i = 0; i < kInlinedProbes; i++) { 7124 for (int i = 0; i < kInlinedProbes; i++) {
7125 // Compute the masked index: (hash + i + i * i) & mask. 7125 // Compute the masked index: (hash + i + i * i) & mask.
7126 Register index = r0; 7126 Register index = r0;
7127 // Capacity is smi 2^n. 7127 // Capacity is smi 2^n.
7128 __ mov(index, FieldOperand(properties, kCapacityOffset)); 7128 __ mov(index, FieldOperand(properties, kCapacityOffset));
7129 __ dec(index); 7129 __ dec(index);
7130 __ and_(index, 7130 __ and_(index,
7131 Immediate(Smi::FromInt(name->Hash() + 7131 Immediate(Smi::FromInt(name->Hash() +
7132 StringDictionary::GetProbeOffset(i)))); 7132 NameDictionary::GetProbeOffset(i))));
7133 7133
7134 // Scale the index by multiplying by the entry size. 7134 // Scale the index by multiplying by the entry size.
7135 ASSERT(StringDictionary::kEntrySize == 3); 7135 ASSERT(NameDictionary::kEntrySize == 3);
7136 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. 7136 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3.
7137 Register entity_name = r0; 7137 Register entity_name = r0;
7138 // Having undefined at this place means the name is not contained. 7138 // Having undefined at this place means the name is not contained.
7139 ASSERT_EQ(kSmiTagSize, 1); 7139 ASSERT_EQ(kSmiTagSize, 1);
7140 __ mov(entity_name, Operand(properties, index, times_half_pointer_size, 7140 __ mov(entity_name, Operand(properties, index, times_half_pointer_size,
7141 kElementsStartOffset - kHeapObjectTag)); 7141 kElementsStartOffset - kHeapObjectTag));
7142 __ cmp(entity_name, masm->isolate()->factory()->undefined_value()); 7142 __ cmp(entity_name, masm->isolate()->factory()->undefined_value());
7143 __ j(equal, done); 7143 __ j(equal, done);
7144 7144
7145 // Stop if found the property. 7145 // Stop if found the property.
7146 __ cmp(entity_name, Handle<String>(name)); 7146 __ cmp(entity_name, Handle<Name>(name));
7147 __ j(equal, miss); 7147 __ j(equal, miss);
7148 7148
7149 Label the_hole; 7149 Label good;
7150 // Check for the hole and skip. 7150 // Check for the hole and skip.
7151 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value()); 7151 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value());
7152 __ j(equal, &the_hole, Label::kNear); 7152 __ j(equal, &good, Label::kNear);
7153 7153
7154 // Check if the entry name is not an internalized string. 7154 // Check if the entry name is not a unique name.
7155 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 7155 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
7156 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), 7156 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset),
7157 kIsInternalizedMask); 7157 kIsInternalizedMask);
7158 __ j(zero, miss); 7158 __ j(not_zero, &good);
7159 __ bind(&the_hole); 7159 __ cmpb(FieldOperand(entity_name, Map::kInstanceTypeOffset),
7160 static_cast<int8_t>(SYMBOL_TYPE));
7161 __ j(not_equal, miss);
7162 __ bind(&good);
7160 } 7163 }
7161 7164
7162 StringDictionaryLookupStub stub(properties, 7165 NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP);
7163 r0,
7164 r0,
7165 StringDictionaryLookupStub::NEGATIVE_LOOKUP);
7166 __ push(Immediate(Handle<Object>(name))); 7166 __ push(Immediate(Handle<Object>(name)));
7167 __ push(Immediate(name->Hash())); 7167 __ push(Immediate(name->Hash()));
7168 __ CallStub(&stub); 7168 __ CallStub(&stub);
7169 __ test(r0, r0); 7169 __ test(r0, r0);
7170 __ j(not_zero, miss); 7170 __ j(not_zero, miss);
7171 __ jmp(done); 7171 __ jmp(done);
7172 } 7172 }
7173 7173
7174 7174
7175 // Probe the string dictionary in the |elements| register. Jump to the 7175 // Probe the name dictionary in the |elements| register. Jump to the
7176 // |done| label if a property with the given name is found leaving the 7176 // |done| label if a property with the given name is found leaving the
7177 // index into the dictionary in |r0|. Jump to the |miss| label 7177 // index into the dictionary in |r0|. Jump to the |miss| label
7178 // otherwise. 7178 // otherwise.
7179 void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, 7179 void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
7180 Label* miss, 7180 Label* miss,
7181 Label* done, 7181 Label* done,
7182 Register elements, 7182 Register elements,
7183 Register name, 7183 Register name,
7184 Register r0, 7184 Register r0,
7185 Register r1) { 7185 Register r1) {
7186 ASSERT(!elements.is(r0)); 7186 ASSERT(!elements.is(r0));
7187 ASSERT(!elements.is(r1)); 7187 ASSERT(!elements.is(r1));
7188 ASSERT(!name.is(r0)); 7188 ASSERT(!name.is(r0));
7189 ASSERT(!name.is(r1)); 7189 ASSERT(!name.is(r1));
7190 7190
7191 __ AssertString(name); 7191 __ AssertName(name);
7192 7192
7193 __ mov(r1, FieldOperand(elements, kCapacityOffset)); 7193 __ mov(r1, FieldOperand(elements, kCapacityOffset));
7194 __ shr(r1, kSmiTagSize); // convert smi to int 7194 __ shr(r1, kSmiTagSize); // convert smi to int
7195 __ dec(r1); 7195 __ dec(r1);
7196 7196
7197 // Generate an unrolled loop that performs a few probes before 7197 // Generate an unrolled loop that performs a few probes before
7198 // giving up. Measurements done on Gmail indicate that 2 probes 7198 // giving up. Measurements done on Gmail indicate that 2 probes
7199 // cover ~93% of loads from dictionaries. 7199 // cover ~93% of loads from dictionaries.
7200 for (int i = 0; i < kInlinedProbes; i++) { 7200 for (int i = 0; i < kInlinedProbes; i++) {
7201 // Compute the masked index: (hash + i + i * i) & mask. 7201 // Compute the masked index: (hash + i + i * i) & mask.
7202 __ mov(r0, FieldOperand(name, String::kHashFieldOffset)); 7202 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset));
7203 __ shr(r0, String::kHashShift); 7203 __ shr(r0, Name::kHashShift);
7204 if (i > 0) { 7204 if (i > 0) {
7205 __ add(r0, Immediate(StringDictionary::GetProbeOffset(i))); 7205 __ add(r0, Immediate(NameDictionary::GetProbeOffset(i)));
7206 } 7206 }
7207 __ and_(r0, r1); 7207 __ and_(r0, r1);
7208 7208
7209 // Scale the index by multiplying by the entry size. 7209 // Scale the index by multiplying by the entry size.
7210 ASSERT(StringDictionary::kEntrySize == 3); 7210 ASSERT(NameDictionary::kEntrySize == 3);
7211 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3 7211 __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3
7212 7212
7213 // Check if the key is identical to the name. 7213 // Check if the key is identical to the name.
7214 __ cmp(name, Operand(elements, 7214 __ cmp(name, Operand(elements,
7215 r0, 7215 r0,
7216 times_4, 7216 times_4,
7217 kElementsStartOffset - kHeapObjectTag)); 7217 kElementsStartOffset - kHeapObjectTag));
7218 __ j(equal, done); 7218 __ j(equal, done);
7219 } 7219 }
7220 7220
7221 StringDictionaryLookupStub stub(elements, 7221 NameDictionaryLookupStub stub(elements, r1, r0, POSITIVE_LOOKUP);
7222 r1,
7223 r0,
7224 POSITIVE_LOOKUP);
7225 __ push(name); 7222 __ push(name);
7226 __ mov(r0, FieldOperand(name, String::kHashFieldOffset)); 7223 __ mov(r0, FieldOperand(name, Name::kHashFieldOffset));
7227 __ shr(r0, String::kHashShift); 7224 __ shr(r0, Name::kHashShift);
7228 __ push(r0); 7225 __ push(r0);
7229 __ CallStub(&stub); 7226 __ CallStub(&stub);
7230 7227
7231 __ test(r1, r1); 7228 __ test(r1, r1);
7232 __ j(zero, miss); 7229 __ j(zero, miss);
7233 __ jmp(done); 7230 __ jmp(done);
7234 } 7231 }
7235 7232
7236 7233
7237 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { 7234 void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
7238 // This stub overrides SometimesSetsUpAFrame() to return false. That means 7235 // This stub overrides SometimesSetsUpAFrame() to return false. That means
7239 // we cannot call anything that could cause a GC from this stub. 7236 // we cannot call anything that could cause a GC from this stub.
7240 // Stack frame on entry: 7237 // Stack frame on entry:
7241 // esp[0 * kPointerSize]: return address. 7238 // esp[0 * kPointerSize]: return address.
7242 // esp[1 * kPointerSize]: key's hash. 7239 // esp[1 * kPointerSize]: key's hash.
7243 // esp[2 * kPointerSize]: key. 7240 // esp[2 * kPointerSize]: key.
7244 // Registers: 7241 // Registers:
7245 // dictionary_: StringDictionary to probe. 7242 // dictionary_: NameDictionary to probe.
7246 // result_: used as scratch. 7243 // result_: used as scratch.
7247 // index_: will hold an index of entry if lookup is successful. 7244 // index_: will hold an index of entry if lookup is successful.
7248 // might alias with result_. 7245 // might alias with result_.
7249 // Returns: 7246 // Returns:
7250 // result_ is zero if lookup failed, non zero otherwise. 7247 // result_ is zero if lookup failed, non zero otherwise.
7251 7248
7252 Label in_dictionary, maybe_in_dictionary, not_in_dictionary; 7249 Label in_dictionary, maybe_in_dictionary, not_in_dictionary;
7253 7250
7254 Register scratch = result_; 7251 Register scratch = result_;
7255 7252
7256 __ mov(scratch, FieldOperand(dictionary_, kCapacityOffset)); 7253 __ mov(scratch, FieldOperand(dictionary_, kCapacityOffset));
7257 __ dec(scratch); 7254 __ dec(scratch);
7258 __ SmiUntag(scratch); 7255 __ SmiUntag(scratch);
7259 __ push(scratch); 7256 __ push(scratch);
7260 7257
7261 // If names of slots in range from 1 to kProbes - 1 for the hash value are 7258 // If names of slots in range from 1 to kProbes - 1 for the hash value are
7262 // not equal to the name and kProbes-th slot is not used (its name is the 7259 // not equal to the name and kProbes-th slot is not used (its name is the
7263 // undefined value), it guarantees the hash table doesn't contain the 7260 // undefined value), it guarantees the hash table doesn't contain the
7264 // property. It's true even if some slots represent deleted properties 7261 // property. It's true even if some slots represent deleted properties
7265 // (their names are the null value). 7262 // (their names are the null value).
7266 for (int i = kInlinedProbes; i < kTotalProbes; i++) { 7263 for (int i = kInlinedProbes; i < kTotalProbes; i++) {
7267 // Compute the masked index: (hash + i + i * i) & mask. 7264 // Compute the masked index: (hash + i + i * i) & mask.
7268 __ mov(scratch, Operand(esp, 2 * kPointerSize)); 7265 __ mov(scratch, Operand(esp, 2 * kPointerSize));
7269 if (i > 0) { 7266 if (i > 0) {
7270 __ add(scratch, Immediate(StringDictionary::GetProbeOffset(i))); 7267 __ add(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
7271 } 7268 }
7272 __ and_(scratch, Operand(esp, 0)); 7269 __ and_(scratch, Operand(esp, 0));
7273 7270
7274 // Scale the index by multiplying by the entry size. 7271 // Scale the index by multiplying by the entry size.
7275 ASSERT(StringDictionary::kEntrySize == 3); 7272 ASSERT(NameDictionary::kEntrySize == 3);
7276 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3. 7273 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3.
7277 7274
7278 // Having undefined at this place means the name is not contained. 7275 // Having undefined at this place means the name is not contained.
7279 ASSERT_EQ(kSmiTagSize, 1); 7276 ASSERT_EQ(kSmiTagSize, 1);
7280 __ mov(scratch, Operand(dictionary_, 7277 __ mov(scratch, Operand(dictionary_,
7281 index_, 7278 index_,
7282 times_pointer_size, 7279 times_pointer_size,
7283 kElementsStartOffset - kHeapObjectTag)); 7280 kElementsStartOffset - kHeapObjectTag));
7284 __ cmp(scratch, masm->isolate()->factory()->undefined_value()); 7281 __ cmp(scratch, masm->isolate()->factory()->undefined_value());
7285 __ j(equal, &not_in_dictionary); 7282 __ j(equal, &not_in_dictionary);
7286 7283
7287 // Stop if found the property. 7284 // Stop if found the property.
7288 __ cmp(scratch, Operand(esp, 3 * kPointerSize)); 7285 __ cmp(scratch, Operand(esp, 3 * kPointerSize));
7289 __ j(equal, &in_dictionary); 7286 __ j(equal, &in_dictionary);
7290 7287
7291 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 7288 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
7292 // If we hit a key that is not an internalized string during negative 7289 // If we hit a key that is not a unique name during negative
7293 // lookup we have to bailout as this key might be equal to the 7290 // lookup we have to bailout as this key might be equal to the
7294 // key we are looking for. 7291 // key we are looking for.
7295 7292
7296 // Check if the entry name is not an internalized string. 7293 // Check if the entry name is not a unique name.
7294 Label cont;
7297 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 7295 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
7298 __ test_b(FieldOperand(scratch, Map::kInstanceTypeOffset), 7296 __ test_b(FieldOperand(scratch, Map::kInstanceTypeOffset),
7299 kIsInternalizedMask); 7297 kIsInternalizedMask);
7300 __ j(zero, &maybe_in_dictionary); 7298 __ j(not_zero, &cont);
7299 __ cmpb(FieldOperand(scratch, Map::kInstanceTypeOffset),
7300 static_cast<int8_t>(SYMBOL_TYPE));
7301 __ j(not_equal, &maybe_in_dictionary);
7302 __ bind(&cont);
7301 } 7303 }
7302 } 7304 }
7303 7305
7304 __ bind(&maybe_in_dictionary); 7306 __ bind(&maybe_in_dictionary);
7305 // If we are doing negative lookup then probing failure should be 7307 // If we are doing negative lookup then probing failure should be
7306 // treated as a lookup success. For positive lookup probing failure 7308 // treated as a lookup success. For positive lookup probing failure
7307 // should be treated as lookup failure. 7309 // should be treated as lookup failure.
7308 if (mode_ == POSITIVE_LOOKUP) { 7310 if (mode_ == POSITIVE_LOOKUP) {
7309 __ mov(result_, Immediate(0)); 7311 __ mov(result_, Immediate(0));
7310 __ Drop(1); 7312 __ Drop(1);
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
7744 // Restore ecx. 7746 // Restore ecx.
7745 __ pop(ecx); 7747 __ pop(ecx);
7746 __ ret(0); 7748 __ ret(0);
7747 } 7749 }
7748 7750
7749 #undef __ 7751 #undef __
7750 7752
7751 } } // namespace v8::internal 7753 } } // namespace v8::internal
7752 7754
7753 #endif // V8_TARGET_ARCH_IA32 7755 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698