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

Side by Side Diff: src/x64/code-stubs-x64.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/x64/code-stubs-x64.h ('k') | src/x64/ic-x64.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 6084 matching lines...) Expand 10 before | Expand all | Expand 10 after
6095 __ lea(rdi, FieldOperand(rax, Code::kHeaderSize)); 6095 __ lea(rdi, FieldOperand(rax, Code::kHeaderSize));
6096 __ pop(rax); 6096 __ pop(rax);
6097 __ pop(rdx); 6097 __ pop(rdx);
6098 } 6098 }
6099 6099
6100 // Do a tail call to the rewritten stub. 6100 // Do a tail call to the rewritten stub.
6101 __ jmp(rdi); 6101 __ jmp(rdi);
6102 } 6102 }
6103 6103
6104 6104
6105 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, 6105 void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
6106 Label* miss, 6106 Label* miss,
6107 Label* done, 6107 Label* done,
6108 Register properties, 6108 Register properties,
6109 Handle<String> name, 6109 Handle<Name> name,
6110 Register r0) { 6110 Register r0) {
6111 ASSERT(name->IsUniqueName());
6111 // If names of slots in range from 1 to kProbes - 1 for the hash value are 6112 // If names of slots in range from 1 to kProbes - 1 for the hash value are
6112 // not equal to the name and kProbes-th slot is not used (its name is the 6113 // not equal to the name and kProbes-th slot is not used (its name is the
6113 // undefined value), it guarantees the hash table doesn't contain the 6114 // undefined value), it guarantees the hash table doesn't contain the
6114 // property. It's true even if some slots represent deleted properties 6115 // property. It's true even if some slots represent deleted properties
6115 // (their names are the hole value). 6116 // (their names are the hole value).
6116 for (int i = 0; i < kInlinedProbes; i++) { 6117 for (int i = 0; i < kInlinedProbes; i++) {
6117 // r0 points to properties hash. 6118 // r0 points to properties hash.
6118 // Compute the masked index: (hash + i + i * i) & mask. 6119 // Compute the masked index: (hash + i + i * i) & mask.
6119 Register index = r0; 6120 Register index = r0;
6120 // Capacity is smi 2^n. 6121 // Capacity is smi 2^n.
6121 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); 6122 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset));
6122 __ decl(index); 6123 __ decl(index);
6123 __ and_(index, 6124 __ and_(index,
6124 Immediate(name->Hash() + StringDictionary::GetProbeOffset(i))); 6125 Immediate(name->Hash() + NameDictionary::GetProbeOffset(i)));
6125 6126
6126 // Scale the index by multiplying by the entry size. 6127 // Scale the index by multiplying by the entry size.
6127 ASSERT(StringDictionary::kEntrySize == 3); 6128 ASSERT(NameDictionary::kEntrySize == 3);
6128 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. 6129 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3.
6129 6130
6130 Register entity_name = r0; 6131 Register entity_name = r0;
6131 // Having undefined at this place means the name is not contained. 6132 // Having undefined at this place means the name is not contained.
6132 ASSERT_EQ(kSmiTagSize, 1); 6133 ASSERT_EQ(kSmiTagSize, 1);
6133 __ movq(entity_name, Operand(properties, 6134 __ movq(entity_name, Operand(properties,
6134 index, 6135 index,
6135 times_pointer_size, 6136 times_pointer_size,
6136 kElementsStartOffset - kHeapObjectTag)); 6137 kElementsStartOffset - kHeapObjectTag));
6137 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); 6138 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value());
6138 __ j(equal, done); 6139 __ j(equal, done);
6139 6140
6140 // Stop if found the property. 6141 // Stop if found the property.
6141 __ Cmp(entity_name, Handle<String>(name)); 6142 __ Cmp(entity_name, Handle<Name>(name));
6142 __ j(equal, miss); 6143 __ j(equal, miss);
6143 6144
6144 Label the_hole; 6145 Label good;
6145 // Check for the hole and skip. 6146 // Check for the hole and skip.
6146 __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex); 6147 __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex);
6147 __ j(equal, &the_hole, Label::kNear); 6148 __ j(equal, &good, Label::kNear);
6148 6149
6149 // Check if the entry name is not an internalized string. 6150 // Check if the entry name is not a unique name.
6150 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 6151 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
6151 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), 6152 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset),
6152 Immediate(kIsInternalizedMask)); 6153 Immediate(kIsInternalizedMask));
6153 __ j(zero, miss); 6154 __ j(not_zero, &good, Label::kNear);
6155 __ cmpb(FieldOperand(entity_name, Map::kInstanceTypeOffset),
6156 Immediate(static_cast<int8_t>(SYMBOL_TYPE)));
6157 __ j(not_equal, miss);
6154 6158
6155 __ bind(&the_hole); 6159 __ bind(&good);
6156 } 6160 }
6157 6161
6158 StringDictionaryLookupStub stub(properties, 6162 NameDictionaryLookupStub stub(properties, r0, r0, NEGATIVE_LOOKUP);
6159 r0,
6160 r0,
6161 StringDictionaryLookupStub::NEGATIVE_LOOKUP);
6162 __ Push(Handle<Object>(name)); 6163 __ Push(Handle<Object>(name));
6163 __ push(Immediate(name->Hash())); 6164 __ push(Immediate(name->Hash()));
6164 __ CallStub(&stub); 6165 __ CallStub(&stub);
6165 __ testq(r0, r0); 6166 __ testq(r0, r0);
6166 __ j(not_zero, miss); 6167 __ j(not_zero, miss);
6167 __ jmp(done); 6168 __ jmp(done);
6168 } 6169 }
6169 6170
6170 6171
6171 // Probe the string dictionary in the |elements| register. Jump to the 6172 // Probe the name dictionary in the |elements| register. Jump to the
6172 // |done| label if a property with the given name is found leaving the 6173 // |done| label if a property with the given name is found leaving the
6173 // index into the dictionary in |r1|. Jump to the |miss| label 6174 // index into the dictionary in |r1|. Jump to the |miss| label
6174 // otherwise. 6175 // otherwise.
6175 void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, 6176 void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm,
6176 Label* miss, 6177 Label* miss,
6177 Label* done, 6178 Label* done,
6178 Register elements, 6179 Register elements,
6179 Register name, 6180 Register name,
6180 Register r0, 6181 Register r0,
6181 Register r1) { 6182 Register r1) {
6182 ASSERT(!elements.is(r0)); 6183 ASSERT(!elements.is(r0));
6183 ASSERT(!elements.is(r1)); 6184 ASSERT(!elements.is(r1));
6184 ASSERT(!name.is(r0)); 6185 ASSERT(!name.is(r0));
6185 ASSERT(!name.is(r1)); 6186 ASSERT(!name.is(r1));
6186 6187
6187 __ AssertString(name); 6188 __ AssertName(name);
6188 6189
6189 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset)); 6190 __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset));
6190 __ decl(r0); 6191 __ decl(r0);
6191 6192
6192 for (int i = 0; i < kInlinedProbes; i++) { 6193 for (int i = 0; i < kInlinedProbes; i++) {
6193 // Compute the masked index: (hash + i + i * i) & mask. 6194 // Compute the masked index: (hash + i + i * i) & mask.
6194 __ movl(r1, FieldOperand(name, String::kHashFieldOffset)); 6195 __ movl(r1, FieldOperand(name, Name::kHashFieldOffset));
6195 __ shrl(r1, Immediate(String::kHashShift)); 6196 __ shrl(r1, Immediate(Name::kHashShift));
6196 if (i > 0) { 6197 if (i > 0) {
6197 __ addl(r1, Immediate(StringDictionary::GetProbeOffset(i))); 6198 __ addl(r1, Immediate(NameDictionary::GetProbeOffset(i)));
6198 } 6199 }
6199 __ and_(r1, r0); 6200 __ and_(r1, r0);
6200 6201
6201 // Scale the index by multiplying by the entry size. 6202 // Scale the index by multiplying by the entry size.
6202 ASSERT(StringDictionary::kEntrySize == 3); 6203 ASSERT(NameDictionary::kEntrySize == 3);
6203 __ lea(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 6204 __ lea(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3
6204 6205
6205 // Check if the key is identical to the name. 6206 // Check if the key is identical to the name.
6206 __ cmpq(name, Operand(elements, r1, times_pointer_size, 6207 __ cmpq(name, Operand(elements, r1, times_pointer_size,
6207 kElementsStartOffset - kHeapObjectTag)); 6208 kElementsStartOffset - kHeapObjectTag));
6208 __ j(equal, done); 6209 __ j(equal, done);
6209 } 6210 }
6210 6211
6211 StringDictionaryLookupStub stub(elements, 6212 NameDictionaryLookupStub stub(elements, r0, r1, POSITIVE_LOOKUP);
6212 r0,
6213 r1,
6214 POSITIVE_LOOKUP);
6215 __ push(name); 6213 __ push(name);
6216 __ movl(r0, FieldOperand(name, String::kHashFieldOffset)); 6214 __ movl(r0, FieldOperand(name, Name::kHashFieldOffset));
6217 __ shrl(r0, Immediate(String::kHashShift)); 6215 __ shrl(r0, Immediate(Name::kHashShift));
6218 __ push(r0); 6216 __ push(r0);
6219 __ CallStub(&stub); 6217 __ CallStub(&stub);
6220 6218
6221 __ testq(r0, r0); 6219 __ testq(r0, r0);
6222 __ j(zero, miss); 6220 __ j(zero, miss);
6223 __ jmp(done); 6221 __ jmp(done);
6224 } 6222 }
6225 6223
6226 6224
6227 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { 6225 void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
6228 // This stub overrides SometimesSetsUpAFrame() to return false. That means 6226 // This stub overrides SometimesSetsUpAFrame() to return false. That means
6229 // we cannot call anything that could cause a GC from this stub. 6227 // we cannot call anything that could cause a GC from this stub.
6230 // Stack frame on entry: 6228 // Stack frame on entry:
6231 // esp[0 * kPointerSize]: return address. 6229 // esp[0 * kPointerSize]: return address.
6232 // esp[1 * kPointerSize]: key's hash. 6230 // esp[1 * kPointerSize]: key's hash.
6233 // esp[2 * kPointerSize]: key. 6231 // esp[2 * kPointerSize]: key.
6234 // Registers: 6232 // Registers:
6235 // dictionary_: StringDictionary to probe. 6233 // dictionary_: NameDictionary to probe.
6236 // result_: used as scratch. 6234 // result_: used as scratch.
6237 // index_: will hold an index of entry if lookup is successful. 6235 // index_: will hold an index of entry if lookup is successful.
6238 // might alias with result_. 6236 // might alias with result_.
6239 // Returns: 6237 // Returns:
6240 // result_ is zero if lookup failed, non zero otherwise. 6238 // result_ is zero if lookup failed, non zero otherwise.
6241 6239
6242 Label in_dictionary, maybe_in_dictionary, not_in_dictionary; 6240 Label in_dictionary, maybe_in_dictionary, not_in_dictionary;
6243 6241
6244 Register scratch = result_; 6242 Register scratch = result_;
6245 6243
6246 __ SmiToInteger32(scratch, FieldOperand(dictionary_, kCapacityOffset)); 6244 __ SmiToInteger32(scratch, FieldOperand(dictionary_, kCapacityOffset));
6247 __ decl(scratch); 6245 __ decl(scratch);
6248 __ push(scratch); 6246 __ push(scratch);
6249 6247
6250 // If names of slots in range from 1 to kProbes - 1 for the hash value are 6248 // If names of slots in range from 1 to kProbes - 1 for the hash value are
6251 // not equal to the name and kProbes-th slot is not used (its name is the 6249 // not equal to the name and kProbes-th slot is not used (its name is the
6252 // undefined value), it guarantees the hash table doesn't contain the 6250 // undefined value), it guarantees the hash table doesn't contain the
6253 // property. It's true even if some slots represent deleted properties 6251 // property. It's true even if some slots represent deleted properties
6254 // (their names are the null value). 6252 // (their names are the null value).
6255 for (int i = kInlinedProbes; i < kTotalProbes; i++) { 6253 for (int i = kInlinedProbes; i < kTotalProbes; i++) {
6256 // Compute the masked index: (hash + i + i * i) & mask. 6254 // Compute the masked index: (hash + i + i * i) & mask.
6257 __ movq(scratch, Operand(rsp, 2 * kPointerSize)); 6255 __ movq(scratch, Operand(rsp, 2 * kPointerSize));
6258 if (i > 0) { 6256 if (i > 0) {
6259 __ addl(scratch, Immediate(StringDictionary::GetProbeOffset(i))); 6257 __ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
6260 } 6258 }
6261 __ and_(scratch, Operand(rsp, 0)); 6259 __ and_(scratch, Operand(rsp, 0));
6262 6260
6263 // Scale the index by multiplying by the entry size. 6261 // Scale the index by multiplying by the entry size.
6264 ASSERT(StringDictionary::kEntrySize == 3); 6262 ASSERT(NameDictionary::kEntrySize == 3);
6265 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3. 6263 __ lea(index_, Operand(scratch, scratch, times_2, 0)); // index *= 3.
6266 6264
6267 // Having undefined at this place means the name is not contained. 6265 // Having undefined at this place means the name is not contained.
6268 __ movq(scratch, Operand(dictionary_, 6266 __ movq(scratch, Operand(dictionary_,
6269 index_, 6267 index_,
6270 times_pointer_size, 6268 times_pointer_size,
6271 kElementsStartOffset - kHeapObjectTag)); 6269 kElementsStartOffset - kHeapObjectTag));
6272 6270
6273 __ Cmp(scratch, masm->isolate()->factory()->undefined_value()); 6271 __ Cmp(scratch, masm->isolate()->factory()->undefined_value());
6274 __ j(equal, &not_in_dictionary); 6272 __ j(equal, &not_in_dictionary);
6275 6273
6276 // Stop if found the property. 6274 // Stop if found the property.
6277 __ cmpq(scratch, Operand(rsp, 3 * kPointerSize)); 6275 __ cmpq(scratch, Operand(rsp, 3 * kPointerSize));
6278 __ j(equal, &in_dictionary); 6276 __ j(equal, &in_dictionary);
6279 6277
6280 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 6278 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
6281 // If we hit a non internalized string key during negative lookup 6279 // If we hit a key that is not a unique name during negative
6282 // we have to bailout as this key might be equal to the 6280 // lookup we have to bailout as this key might be equal to the
6283 // key we are looking for. 6281 // key we are looking for.
6284 6282
6285 // Check if the entry name is not an internalized string. 6283 // Check if the entry name is not a unique name.
6284 Label cont;
6286 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 6285 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
6287 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), 6286 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset),
6288 Immediate(kIsInternalizedMask)); 6287 Immediate(kIsInternalizedMask));
6289 __ j(zero, &maybe_in_dictionary); 6288 __ j(not_zero, &cont);
6289 __ cmpb(FieldOperand(scratch, Map::kInstanceTypeOffset),
6290 Immediate(static_cast<int8_t>(SYMBOL_TYPE)));
6291 __ j(not_equal, &maybe_in_dictionary);
6292 __ bind(&cont);
6290 } 6293 }
6291 } 6294 }
6292 6295
6293 __ bind(&maybe_in_dictionary); 6296 __ bind(&maybe_in_dictionary);
6294 // If we are doing negative lookup then probing failure should be 6297 // If we are doing negative lookup then probing failure should be
6295 // treated as a lookup success. For positive lookup probing failure 6298 // treated as a lookup success. For positive lookup probing failure
6296 // should be treated as lookup failure. 6299 // should be treated as lookup failure.
6297 if (mode_ == POSITIVE_LOOKUP) { 6300 if (mode_ == POSITIVE_LOOKUP) {
6298 __ movq(scratch, Immediate(0)); 6301 __ movq(scratch, Immediate(0));
6299 __ Drop(1); 6302 __ Drop(1);
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
6769 #endif 6772 #endif
6770 6773
6771 __ Ret(); 6774 __ Ret();
6772 } 6775 }
6773 6776
6774 #undef __ 6777 #undef __
6775 6778
6776 } } // namespace v8::internal 6779 } } // namespace v8::internal
6777 6780
6778 #endif // V8_TARGET_ARCH_X64 6781 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698