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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2277363002: [stubs] Consolidate TryToName implementation (Closed)
Patch Set: fix strings of uncacheable indices Created 4 years, 3 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 2239 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 } 2250 }
2251 } 2251 }
2252 2252
2253 void CodeStubAssembler::Use(Label* label) { 2253 void CodeStubAssembler::Use(Label* label) {
2254 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); 2254 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
2255 } 2255 }
2256 2256
2257 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, 2257 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
2258 Variable* var_index, Label* if_keyisunique, 2258 Variable* var_index, Label* if_keyisunique,
2259 Label* if_bailout) { 2259 Label* if_bailout) {
2260 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); 2260 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep());
2261 Comment("TryToName"); 2261 Comment("TryToName");
2262 2262
2263 Label if_keyissmi(this), if_keyisnotsmi(this); 2263 Label if_hascachedindex(this), if_keyisnotindex(this);
2264 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); 2264 // Handle Smi and HeapNumber keys.
2265 Bind(&if_keyissmi); 2265 var_index->Bind(TryToIntptr(key, &if_keyisnotindex));
2266 { 2266 Goto(if_keyisindex);
2267 // Negative smi keys are named properties. Handle in the runtime.
2268 GotoUnless(WordIsPositiveSmi(key), if_bailout);
2269 2267
2270 var_index->Bind(SmiToWord32(key)); 2268 Bind(&if_keyisnotindex);
2271 Goto(if_keyisindex);
2272 }
2273
2274 Bind(&if_keyisnotsmi);
2275
2276 Node* key_instance_type = LoadInstanceType(key); 2269 Node* key_instance_type = LoadInstanceType(key);
2277 // Symbols are unique. 2270 // Symbols are unique.
2278 GotoIf(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)), 2271 GotoIf(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)),
2279 if_keyisunique); 2272 if_keyisunique);
2273 // Miss if |key| is not a String.
2274 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
2275 GotoIf(
2276 Int32GreaterThan(key_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)),
2277 if_bailout);
2278 // |key| is a String. Check if it has a cached array index.
2279 Node* hash = LoadNameHashField(key);
2280 Node* contains_index =
2281 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
2282 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex);
2283 // No cached array index. Maybe it's an uncacheable index?
Igor Sheludko 2016/09/06 15:35:27 How about saying like this to be more clear: // No
2284 Node* not_an_index =
2285 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
2286 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout);
2287 // Finally, check if |key| is internalized.
2288 STATIC_ASSERT(kNotInternalizedTag != 0);
2289 Node* not_internalized =
2290 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
2291 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout);
2292 Goto(if_keyisunique);
2280 2293
2281 Label if_keyisinternalized(this); 2294 Bind(&if_hascachedindex);
2282 Node* bits =
2283 WordAnd(key_instance_type,
2284 Int32Constant(kIsNotStringMask | kIsNotInternalizedMask));
2285 Branch(Word32Equal(bits, Int32Constant(kStringTag | kInternalizedTag)),
2286 &if_keyisinternalized, if_bailout);
2287 Bind(&if_keyisinternalized);
2288
2289 // Check whether the key is an array index passed in as string. Handle
2290 // uniform with smi keys if so.
2291 // TODO(verwaest): Also support non-internalized strings.
2292 Node* hash = LoadNameHashField(key);
2293 Node* bit = Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
2294 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_keyisunique);
2295 // Key is an index. Check if it is small enough to be encoded in the
2296 // hash_field. Handle too big array index in runtime.
2297 bit = Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
2298 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_bailout);
2299 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); 2295 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash));
2300 Goto(if_keyisindex); 2296 Goto(if_keyisindex);
2301 } 2297 }
2302 2298
2303 template <typename Dictionary> 2299 template <typename Dictionary>
2304 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { 2300 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
2305 Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize)); 2301 Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize));
2306 return Int32Add(entry_index, 2302 return Int32Add(entry_index,
2307 Int32Constant(Dictionary::kElementsStartIndex + field_index)); 2303 Int32Constant(Dictionary::kElementsStartIndex + field_index));
2308 } 2304 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 Word32Shl(hash, Int32Constant(15))); 2378 Word32Shl(hash, Int32Constant(15)));
2383 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12))); 2379 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
2384 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2))); 2380 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2)));
2385 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4))); 2381 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4)));
2386 hash = Int32Mul(hash, Int32Constant(2057)); 2382 hash = Int32Mul(hash, Int32Constant(2057));
2387 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); 2383 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
2388 return Word32And(hash, Int32Constant(0x3fffffff)); 2384 return Word32And(hash, Int32Constant(0x3fffffff));
2389 } 2385 }
2390 2386
2391 template <typename Dictionary> 2387 template <typename Dictionary>
2392 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key, 2388 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
2389 Node* intptr_index,
2393 Label* if_found, 2390 Label* if_found,
2394 Variable* var_entry, 2391 Variable* var_entry,
2395 Label* if_not_found) { 2392 Label* if_not_found) {
2396 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep()); 2393 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep());
2397 Comment("NumberDictionaryLookup"); 2394 Comment("NumberDictionaryLookup");
2398 2395
2399 Node* capacity = LoadAndUntagToWord32FixedArrayElement( 2396 Node* capacity = LoadAndUntagToWord32FixedArrayElement(
2400 dictionary, Int32Constant(Dictionary::kCapacityIndex)); 2397 dictionary, Int32Constant(Dictionary::kCapacityIndex));
2401 Node* mask = Int32Sub(capacity, Int32Constant(1)); 2398 Node* mask = Int32Sub(capacity, Int32Constant(1));
2402 2399
2403 Node* seed; 2400 Node* seed;
2404 if (Dictionary::ShapeT::UsesSeed) { 2401 if (Dictionary::ShapeT::UsesSeed) {
2405 seed = HashSeed(); 2402 seed = HashSeed();
2406 } else { 2403 } else {
2407 seed = Int32Constant(kZeroHashSeed); 2404 seed = Int32Constant(kZeroHashSeed);
2408 } 2405 }
2409 Node* hash = ComputeIntegerHash(key, seed); 2406 Node* hash = ComputeIntegerHash(intptr_index, seed);
2410 Node* key_as_float64 = ChangeUint32ToFloat64(key); 2407 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
2411 2408
2412 // See Dictionary::FirstProbe(). 2409 // See Dictionary::FirstProbe().
2413 Node* count = Int32Constant(0); 2410 Node* count = Int32Constant(0);
2414 Node* entry = Word32And(hash, mask); 2411 Node* entry = Word32And(hash, mask);
2415 2412
2416 Node* undefined = UndefinedConstant(); 2413 Node* undefined = UndefinedConstant();
2417 Node* the_hole = TheHoleConstant(); 2414 Node* the_hole = TheHoleConstant();
2418 2415
2419 Variable var_count(this, MachineRepresentation::kWord32); 2416 Variable var_count(this, MachineRepresentation::kWord32);
2420 Variable* loop_vars[] = {&var_count, var_entry}; 2417 Variable* loop_vars[] = {&var_count, var_entry};
2421 Label loop(this, 2, loop_vars); 2418 Label loop(this, 2, loop_vars);
2422 var_count.Bind(count); 2419 var_count.Bind(count);
2423 var_entry->Bind(entry); 2420 var_entry->Bind(entry);
2424 Goto(&loop); 2421 Goto(&loop);
2425 Bind(&loop); 2422 Bind(&loop);
2426 { 2423 {
2427 Node* count = var_count.value(); 2424 Node* count = var_count.value();
2428 Node* entry = var_entry->value(); 2425 Node* entry = var_entry->value();
2429 2426
2430 Node* index = EntryToIndex<Dictionary>(entry); 2427 Node* index = EntryToIndex<Dictionary>(entry);
2431 Node* current = LoadFixedArrayElement(dictionary, index); 2428 Node* current = LoadFixedArrayElement(dictionary, index);
2432 GotoIf(WordEqual(current, undefined), if_not_found); 2429 GotoIf(WordEqual(current, undefined), if_not_found);
2433 Label next_probe(this); 2430 Label next_probe(this);
2434 { 2431 {
2435 Label if_currentissmi(this), if_currentisnotsmi(this); 2432 Label if_currentissmi(this), if_currentisnotsmi(this);
2436 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); 2433 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi);
2437 Bind(&if_currentissmi); 2434 Bind(&if_currentissmi);
2438 { 2435 {
2439 Node* current_value = SmiToWord32(current); 2436 Node* current_value = SmiUntag(current);
2440 Branch(Word32Equal(current_value, key), if_found, &next_probe); 2437 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe);
2441 } 2438 }
2442 Bind(&if_currentisnotsmi); 2439 Bind(&if_currentisnotsmi);
2443 { 2440 {
2444 GotoIf(WordEqual(current, the_hole), &next_probe); 2441 GotoIf(WordEqual(current, the_hole), &next_probe);
2445 // Current must be the Number. 2442 // Current must be the Number.
2446 Node* current_value = LoadHeapNumberValue(current); 2443 Node* current_value = LoadHeapNumberValue(current);
2447 Branch(Float64Equal(current_value, key_as_float64), if_found, 2444 Branch(Float64Equal(current_value, key_as_float64), if_found,
2448 &next_probe); 2445 &next_probe);
2449 } 2446 }
2450 } 2447 }
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2810 // Call the accessor. 2807 // Call the accessor.
2811 Callable callable = CodeFactory::Call(isolate()); 2808 Callable callable = CodeFactory::Call(isolate());
2812 Node* result = CallJS(callable, context, getter, receiver); 2809 Node* result = CallJS(callable, context, getter, receiver);
2813 var_value->Bind(result); 2810 var_value->Bind(result);
2814 Goto(if_found_value); 2811 Goto(if_found_value);
2815 } 2812 }
2816 } 2813 }
2817 } 2814 }
2818 2815
2819 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, 2816 void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
2820 Node* instance_type, Node* index, 2817 Node* instance_type,
2821 Label* if_found, Label* if_not_found, 2818 Node* intptr_index, Label* if_found,
2819 Label* if_not_found,
2822 Label* if_bailout) { 2820 Label* if_bailout) {
2823 // Handle special objects in runtime. 2821 // Handle special objects in runtime.
2824 GotoIf(Int32LessThanOrEqual(instance_type, 2822 GotoIf(Int32LessThanOrEqual(instance_type,
2825 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 2823 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
2826 if_bailout); 2824 if_bailout);
2827 2825
2828 Node* bit_field2 = LoadMapBitField2(map); 2826 Node* bit_field2 = LoadMapBitField2(map);
2829 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2); 2827 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2);
2830 2828
2831 // TODO(verwaest): Support other elements kinds as well. 2829 // TODO(verwaest): Support other elements kinds as well.
2832 Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this), 2830 Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this),
2833 if_isfaststringwrapper(this), if_isslowstringwrapper(this); 2831 if_isfaststringwrapper(this), if_isslowstringwrapper(this), if_oob(this);
2834 // clang-format off 2832 // clang-format off
2835 int32_t values[] = { 2833 int32_t values[] = {
2836 // Handled by {if_isobjectorsmi}. 2834 // Handled by {if_isobjectorsmi}.
2837 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, 2835 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
2838 FAST_HOLEY_ELEMENTS, 2836 FAST_HOLEY_ELEMENTS,
2839 // Handled by {if_isdouble}. 2837 // Handled by {if_isdouble}.
2840 FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, 2838 FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
2841 // Handled by {if_isdictionary}. 2839 // Handled by {if_isdictionary}.
2842 DICTIONARY_ELEMENTS, 2840 DICTIONARY_ELEMENTS,
2843 // Handled by {if_isfaststringwrapper}. 2841 // Handled by {if_isfaststringwrapper}.
(...skipping 14 matching lines...) Expand all
2858 }; 2856 };
2859 // clang-format on 2857 // clang-format on
2860 STATIC_ASSERT(arraysize(values) == arraysize(labels)); 2858 STATIC_ASSERT(arraysize(values) == arraysize(labels));
2861 Switch(elements_kind, if_bailout, values, labels, arraysize(values)); 2859 Switch(elements_kind, if_bailout, values, labels, arraysize(values));
2862 2860
2863 Bind(&if_isobjectorsmi); 2861 Bind(&if_isobjectorsmi);
2864 { 2862 {
2865 Node* elements = LoadElements(object); 2863 Node* elements = LoadElements(object);
2866 Node* length = LoadAndUntagFixedArrayBaseLength(elements); 2864 Node* length = LoadAndUntagFixedArrayBaseLength(elements);
2867 2865
2868 GotoUnless(Uint32LessThan(index, length), if_not_found); 2866 GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob);
2869 2867
2870 Node* element = LoadFixedArrayElement(elements, index); 2868 Node* element =
2869 LoadFixedArrayElement(elements, intptr_index, 0, INTPTR_PARAMETERS);
2871 Node* the_hole = TheHoleConstant(); 2870 Node* the_hole = TheHoleConstant();
2872 Branch(WordEqual(element, the_hole), if_not_found, if_found); 2871 Branch(WordEqual(element, the_hole), if_not_found, if_found);
2873 } 2872 }
2874 Bind(&if_isdouble); 2873 Bind(&if_isdouble);
2875 { 2874 {
2876 Node* elements = LoadElements(object); 2875 Node* elements = LoadElements(object);
2877 Node* length = LoadAndUntagFixedArrayBaseLength(elements); 2876 Node* length = LoadAndUntagFixedArrayBaseLength(elements);
2878 2877
2879 GotoUnless(Uint32LessThan(index, length), if_not_found); 2878 GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob);
2880 2879
2881 if (kPointerSize == kDoubleSize) { 2880 if (kPointerSize == kDoubleSize) {
2882 Node* element = 2881 Node* element = LoadFixedDoubleArrayElement(
2883 LoadFixedDoubleArrayElement(elements, index, MachineType::Uint64()); 2882 elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS);
2884 Node* the_hole = Int64Constant(kHoleNanInt64); 2883 Node* the_hole = Int64Constant(kHoleNanInt64);
2885 Branch(Word64Equal(element, the_hole), if_not_found, if_found); 2884 Branch(Word64Equal(element, the_hole), if_not_found, if_found);
2886 } else { 2885 } else {
2887 Node* element_upper = 2886 Node* element_upper = LoadFixedDoubleArrayElement(
2888 LoadFixedDoubleArrayElement(elements, index, MachineType::Uint32(), 2887 elements, intptr_index, MachineType::Uint32(),
2889 kIeeeDoubleExponentWordOffset); 2888 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS);
2890 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), 2889 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
2891 if_not_found, if_found); 2890 if_not_found, if_found);
2892 } 2891 }
2893 } 2892 }
2894 Bind(&if_isdictionary); 2893 Bind(&if_isdictionary);
2895 { 2894 {
2896 Variable var_entry(this, MachineRepresentation::kWord32); 2895 Variable var_entry(this, MachineRepresentation::kWord32);
2897 Node* elements = LoadElements(object); 2896 Node* elements = LoadElements(object);
2898 NumberDictionaryLookup<SeededNumberDictionary>(elements, index, if_found, 2897 NumberDictionaryLookup<SeededNumberDictionary>(
2899 &var_entry, if_not_found); 2898 elements, intptr_index, if_found, &var_entry, if_not_found);
2900 } 2899 }
2901 Bind(&if_isfaststringwrapper); 2900 Bind(&if_isfaststringwrapper);
2902 { 2901 {
2903 AssertInstanceType(object, JS_VALUE_TYPE); 2902 AssertInstanceType(object, JS_VALUE_TYPE);
2904 Node* string = LoadJSValueValue(object); 2903 Node* string = LoadJSValueValue(object);
2905 Assert(Int32LessThan(LoadInstanceType(string), 2904 Assert(Int32LessThan(LoadInstanceType(string),
2906 Int32Constant(FIRST_NONSTRING_TYPE))); 2905 Int32Constant(FIRST_NONSTRING_TYPE)));
2907 Node* length = LoadStringLength(string); 2906 Node* length = LoadStringLength(string);
2908 GotoIf(Uint32LessThan(index, SmiToWord32(length)), if_found); 2907 GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found);
2909 Goto(&if_isobjectorsmi); 2908 Goto(&if_isobjectorsmi);
2910 } 2909 }
2911 Bind(&if_isslowstringwrapper); 2910 Bind(&if_isslowstringwrapper);
2912 { 2911 {
2913 AssertInstanceType(object, JS_VALUE_TYPE); 2912 AssertInstanceType(object, JS_VALUE_TYPE);
2914 Node* string = LoadJSValueValue(object); 2913 Node* string = LoadJSValueValue(object);
2915 Assert(Int32LessThan(LoadInstanceType(string), 2914 Assert(Int32LessThan(LoadInstanceType(string),
2916 Int32Constant(FIRST_NONSTRING_TYPE))); 2915 Int32Constant(FIRST_NONSTRING_TYPE)));
2917 Node* length = LoadStringLength(string); 2916 Node* length = LoadStringLength(string);
2918 GotoIf(Uint32LessThan(index, SmiToWord32(length)), if_found); 2917 GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found);
2919 Goto(&if_isdictionary); 2918 Goto(&if_isdictionary);
2920 } 2919 }
2920 Bind(&if_oob);
2921 {
2922 // Positive OOB indices mean "not found", negative indices must be
2923 // converted to property names.
2924 GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), if_bailout);
2925 Goto(if_not_found);
2926 }
2921 } 2927 }
2922 2928
2923 // Instantiate template methods to workaround GCC compilation issue. 2929 // Instantiate template methods to workaround GCC compilation issue.
2924 template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>( 2930 template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>(
2925 Node*, Node*, Label*, Variable*, Label*); 2931 Node*, Node*, Label*, Variable*, Label*);
2926 template void CodeStubAssembler::NumberDictionaryLookup< 2932 template void CodeStubAssembler::NumberDictionaryLookup<
2927 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); 2933 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*);
2928 2934
2929 void CodeStubAssembler::TryPrototypeChainLookup( 2935 void CodeStubAssembler::TryPrototypeChainLookup(
2930 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder, 2936 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder,
2931 LookupInHolder& lookup_element_in_holder, Label* if_end, 2937 LookupInHolder& lookup_element_in_holder, Label* if_end,
2932 Label* if_bailout) { 2938 Label* if_bailout) {
2933 // Ensure receiver is JSReceiver, otherwise bailout. 2939 // Ensure receiver is JSReceiver, otherwise bailout.
2934 Label if_objectisnotsmi(this); 2940 Label if_objectisnotsmi(this);
2935 Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi); 2941 Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi);
2936 Bind(&if_objectisnotsmi); 2942 Bind(&if_objectisnotsmi);
2937 2943
2938 Node* map = LoadMap(receiver); 2944 Node* map = LoadMap(receiver);
2939 Node* instance_type = LoadMapInstanceType(map); 2945 Node* instance_type = LoadMapInstanceType(map);
2940 { 2946 {
2941 Label if_objectisreceiver(this); 2947 Label if_objectisreceiver(this);
2942 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 2948 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2943 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); 2949 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE);
2944 Branch( 2950 Branch(
2945 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), 2951 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)),
2946 &if_objectisreceiver, if_bailout); 2952 &if_objectisreceiver, if_bailout);
2947 Bind(&if_objectisreceiver); 2953 Bind(&if_objectisreceiver);
2948 } 2954 }
2949 2955
2950 Variable var_index(this, MachineRepresentation::kWord32); 2956 Variable var_index(this, MachineType::PointerRepresentation());
2951 2957
2952 Label if_keyisindex(this), if_iskeyunique(this); 2958 Label if_keyisindex(this), if_iskeyunique(this);
2953 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); 2959 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout);
2954 2960
2955 Bind(&if_iskeyunique); 2961 Bind(&if_iskeyunique);
2956 { 2962 {
2957 Variable var_holder(this, MachineRepresentation::kTagged); 2963 Variable var_holder(this, MachineRepresentation::kTagged);
2958 Variable var_holder_map(this, MachineRepresentation::kTagged); 2964 Variable var_holder_map(this, MachineRepresentation::kTagged);
2959 Variable var_holder_instance_type(this, MachineRepresentation::kWord8); 2965 Variable var_holder_instance_type(this, MachineRepresentation::kWord8);
2960 2966
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3172 } 3178 }
3173 3179
3174 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, 3180 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
3175 ElementsKind kind, 3181 ElementsKind kind,
3176 ParameterMode mode, 3182 ParameterMode mode,
3177 int base_size) { 3183 int base_size) {
3178 bool is_double = IsFastDoubleElementsKind(kind); 3184 bool is_double = IsFastDoubleElementsKind(kind);
3179 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2; 3185 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2;
3180 int element_size = 1 << element_size_shift; 3186 int element_size = 1 << element_size_shift;
3181 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; 3187 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize;
3182 int32_t index = 0; 3188 intptr_t index = 0;
3183 bool constant_index = false; 3189 bool constant_index = false;
3184 if (mode == SMI_PARAMETERS) { 3190 if (mode == SMI_PARAMETERS) {
3185 element_size_shift -= kSmiShiftBits; 3191 element_size_shift -= kSmiShiftBits;
3186 intptr_t temp = 0; 3192 constant_index = ToIntPtrConstant(index_node, index);
3187 constant_index = ToIntPtrConstant(index_node, temp); 3193 index = index >> kSmiShiftBits;
3188 index = temp >> kSmiShiftBits; 3194 } else if (mode == INTEGER_PARAMETERS) {
3195 int32_t temp = 0;
3196 constant_index = ToInt32Constant(index_node, temp);
3197 index = static_cast<intptr_t>(temp);
3189 } else { 3198 } else {
3190 constant_index = ToInt32Constant(index_node, index); 3199 DCHECK(mode == INTPTR_PARAMETERS);
3200 constant_index = ToIntPtrConstant(index_node, index);
3191 } 3201 }
3192 if (constant_index) { 3202 if (constant_index) {
3193 return IntPtrConstant(base_size + element_size * index); 3203 return IntPtrConstant(base_size + element_size * index);
3194 } 3204 }
3195 if (Is64() && mode == INTEGER_PARAMETERS) { 3205 if (Is64() && mode == INTEGER_PARAMETERS) {
3196 index_node = ChangeInt32ToInt64(index_node); 3206 index_node = ChangeInt32ToInt64(index_node);
3197 } 3207 }
3198 if (base_size == 0) { 3208 if (base_size == 0) {
3199 return (element_size_shift >= 0) 3209 return (element_size_shift >= 0)
3200 ? WordShl(index_node, IntPtrConstant(element_size_shift)) 3210 ? WordShl(index_node, IntPtrConstant(element_size_shift))
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3476 var_intptr_key.Bind(SmiUntag(key)); 3486 var_intptr_key.Bind(SmiUntag(key));
3477 Goto(&done); 3487 Goto(&done);
3478 } 3488 }
3479 3489
3480 Bind(&done); 3490 Bind(&done);
3481 return var_intptr_key.value(); 3491 return var_intptr_key.value();
3482 } 3492 }
3483 3493
3484 void CodeStubAssembler::EmitFastElementsBoundsCheck(Node* object, 3494 void CodeStubAssembler::EmitFastElementsBoundsCheck(Node* object,
3485 Node* elements, 3495 Node* elements,
3486 Node* intptr_key, 3496 Node* intptr_index,
3487 Node* is_jsarray_condition, 3497 Node* is_jsarray_condition,
3488 Label* miss) { 3498 Label* miss) {
3489 Variable var_length(this, MachineRepresentation::kTagged); 3499 Variable var_length(this, MachineRepresentation::kTagged);
3490 Label if_array(this), length_loaded(this, &var_length); 3500 Label if_array(this), length_loaded(this, &var_length);
3491 GotoIf(is_jsarray_condition, &if_array); 3501 GotoIf(is_jsarray_condition, &if_array);
3492 { 3502 {
3493 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); 3503 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements)));
3494 Goto(&length_loaded); 3504 Goto(&length_loaded);
3495 } 3505 }
3496 Bind(&if_array); 3506 Bind(&if_array);
3497 { 3507 {
3498 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset))); 3508 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset)));
3499 Goto(&length_loaded); 3509 Goto(&length_loaded);
3500 } 3510 }
3501 Bind(&length_loaded); 3511 Bind(&length_loaded);
3502 GotoUnless(UintPtrLessThan(intptr_key, var_length.value()), miss); 3512 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss);
3503 } 3513 }
3504 3514
3505 // |key| should be untagged (int32).
3506 void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, 3515 void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements,
3507 Node* elements_kind, Node* key, 3516 Node* elements_kind, Node* intptr_index,
3508 Node* is_jsarray_condition, 3517 Node* is_jsarray_condition,
3509 Label* if_hole, Label* rebox_double, 3518 Label* if_hole, Label* rebox_double,
3510 Variable* var_double_value, 3519 Variable* var_double_value,
3511 Label* unimplemented_elements_kind, 3520 Label* unimplemented_elements_kind,
3512 Label* out_of_bounds, Label* miss) { 3521 Label* out_of_bounds, Label* miss) {
3513 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this), 3522 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this),
3514 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), 3523 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this),
3515 if_dictionary(this), unreachable(this); 3524 if_dictionary(this), unreachable(this);
3516 GotoIf( 3525 GotoIf(
3517 IntPtrGreaterThan(elements_kind, IntPtrConstant(LAST_FAST_ELEMENTS_KIND)), 3526 IntPtrGreaterThan(elements_kind, IntPtrConstant(LAST_FAST_ELEMENTS_KIND)),
3518 &if_nonfast); 3527 &if_nonfast);
3519 3528
3520 EmitFastElementsBoundsCheck(object, elements, key, is_jsarray_condition, 3529 EmitFastElementsBoundsCheck(object, elements, intptr_index,
3521 out_of_bounds); 3530 is_jsarray_condition, out_of_bounds);
3522 int32_t kinds[] = {// Handled by if_fast_packed. 3531 int32_t kinds[] = {// Handled by if_fast_packed.
3523 FAST_SMI_ELEMENTS, FAST_ELEMENTS, 3532 FAST_SMI_ELEMENTS, FAST_ELEMENTS,
3524 // Handled by if_fast_holey. 3533 // Handled by if_fast_holey.
3525 FAST_HOLEY_SMI_ELEMENTS, FAST_HOLEY_ELEMENTS, 3534 FAST_HOLEY_SMI_ELEMENTS, FAST_HOLEY_ELEMENTS,
3526 // Handled by if_fast_double. 3535 // Handled by if_fast_double.
3527 FAST_DOUBLE_ELEMENTS, 3536 FAST_DOUBLE_ELEMENTS,
3528 // Handled by if_fast_holey_double. 3537 // Handled by if_fast_holey_double.
3529 FAST_HOLEY_DOUBLE_ELEMENTS}; 3538 FAST_HOLEY_DOUBLE_ELEMENTS};
3530 Label* labels[] = {// FAST_{SMI,}_ELEMENTS 3539 Label* labels[] = {// FAST_{SMI,}_ELEMENTS
3531 &if_fast_packed, &if_fast_packed, 3540 &if_fast_packed, &if_fast_packed,
3532 // FAST_HOLEY_{SMI,}_ELEMENTS 3541 // FAST_HOLEY_{SMI,}_ELEMENTS
3533 &if_fast_holey, &if_fast_holey, 3542 &if_fast_holey, &if_fast_holey,
3534 // FAST_DOUBLE_ELEMENTS 3543 // FAST_DOUBLE_ELEMENTS
3535 &if_fast_double, 3544 &if_fast_double,
3536 // FAST_HOLEY_DOUBLE_ELEMENTS 3545 // FAST_HOLEY_DOUBLE_ELEMENTS
3537 &if_fast_holey_double}; 3546 &if_fast_holey_double};
3538 Switch(elements_kind, unimplemented_elements_kind, kinds, labels, 3547 Switch(elements_kind, unimplemented_elements_kind, kinds, labels,
3539 arraysize(kinds)); 3548 arraysize(kinds));
3540 3549
3541 Bind(&if_fast_packed); 3550 Bind(&if_fast_packed);
3542 { 3551 {
3543 Comment("fast packed elements"); 3552 Comment("fast packed elements");
3544 // TODO(jkummerow): The Load*Element helpers add movsxlq instructions 3553 Return(LoadFixedArrayElement(elements, intptr_index, 0, INTPTR_PARAMETERS));
3545 // on x64 which we don't need here, because |key| is an IntPtr already.
3546 // Do something about that.
3547 Return(LoadFixedArrayElement(elements, key));
3548 } 3554 }
3549 3555
3550 Bind(&if_fast_holey); 3556 Bind(&if_fast_holey);
3551 { 3557 {
3552 Comment("fast holey elements"); 3558 Comment("fast holey elements");
3553 Node* element = LoadFixedArrayElement(elements, key); 3559 Node* element =
3560 LoadFixedArrayElement(elements, intptr_index, 0, INTPTR_PARAMETERS);
3554 GotoIf(WordEqual(element, TheHoleConstant()), if_hole); 3561 GotoIf(WordEqual(element, TheHoleConstant()), if_hole);
3555 Return(element); 3562 Return(element);
3556 } 3563 }
3557 3564
3558 Bind(&if_fast_double); 3565 Bind(&if_fast_double);
3559 { 3566 {
3560 Comment("packed double elements"); 3567 Comment("packed double elements");
3561 var_double_value->Bind( 3568 var_double_value->Bind(LoadFixedDoubleArrayElement(
3562 LoadFixedDoubleArrayElement(elements, key, MachineType::Float64())); 3569 elements, intptr_index, MachineType::Float64(), 0, INTPTR_PARAMETERS));
3563 Goto(rebox_double); 3570 Goto(rebox_double);
3564 } 3571 }
3565 3572
3566 Bind(&if_fast_holey_double); 3573 Bind(&if_fast_holey_double);
3567 { 3574 {
3568 Comment("holey double elements"); 3575 Comment("holey double elements");
3569 if (kPointerSize == kDoubleSize) { 3576 if (kPointerSize == kDoubleSize) {
3570 Node* raw_element = 3577 Node* raw_element = LoadFixedDoubleArrayElement(
3571 LoadFixedDoubleArrayElement(elements, key, MachineType::Uint64()); 3578 elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS);
3572 Node* the_hole = Int64Constant(kHoleNanInt64); 3579 Node* the_hole = Int64Constant(kHoleNanInt64);
3573 GotoIf(Word64Equal(raw_element, the_hole), if_hole); 3580 GotoIf(Word64Equal(raw_element, the_hole), if_hole);
3574 } else { 3581 } else {
3575 Node* element_upper = LoadFixedDoubleArrayElement( 3582 Node* element_upper = LoadFixedDoubleArrayElement(
3576 elements, key, MachineType::Uint32(), kIeeeDoubleExponentWordOffset); 3583 elements, intptr_index, MachineType::Uint32(),
3584 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS);
3577 GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), 3585 GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
3578 if_hole); 3586 if_hole);
3579 } 3587 }
3580 var_double_value->Bind( 3588 var_double_value->Bind(LoadFixedDoubleArrayElement(
3581 LoadFixedDoubleArrayElement(elements, key, MachineType::Float64())); 3589 elements, intptr_index, MachineType::Float64(), 0, INTPTR_PARAMETERS));
3582 Goto(rebox_double); 3590 Goto(rebox_double);
3583 } 3591 }
3584 3592
3585 Bind(&if_nonfast); 3593 Bind(&if_nonfast);
3586 { 3594 {
3587 STATIC_ASSERT(LAST_ELEMENTS_KIND == LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND); 3595 STATIC_ASSERT(LAST_ELEMENTS_KIND == LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
3588 GotoIf(IntPtrGreaterThanOrEqual( 3596 GotoIf(IntPtrGreaterThanOrEqual(
3589 elements_kind, 3597 elements_kind,
3590 IntPtrConstant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND)), 3598 IntPtrConstant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND)),
3591 &if_typed_array); 3599 &if_typed_array);
3592 GotoIf(IntPtrEqual(elements_kind, IntPtrConstant(DICTIONARY_ELEMENTS)), 3600 GotoIf(IntPtrEqual(elements_kind, IntPtrConstant(DICTIONARY_ELEMENTS)),
3593 &if_dictionary); 3601 &if_dictionary);
3594 Goto(unimplemented_elements_kind); 3602 Goto(unimplemented_elements_kind);
3595 } 3603 }
3596 3604
3597 Bind(&if_dictionary); 3605 Bind(&if_dictionary);
3598 { 3606 {
3599 Comment("dictionary elements"); 3607 Comment("dictionary elements");
3600 GotoIf(IntPtrLessThan(key, IntPtrConstant(0)), out_of_bounds); 3608 GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds);
3601 Variable var_entry(this, MachineRepresentation::kWord32); 3609 Variable var_entry(this, MachineRepresentation::kWord32);
3602 Label if_found(this); 3610 Label if_found(this);
3603 NumberDictionaryLookup<SeededNumberDictionary>(elements, key, &if_found, 3611 NumberDictionaryLookup<SeededNumberDictionary>(
3604 &var_entry, if_hole); 3612 elements, intptr_index, &if_found, &var_entry, if_hole);
3605 Bind(&if_found); 3613 Bind(&if_found);
3606 // Check that the value is a data property. 3614 // Check that the value is a data property.
3607 Node* details_index = EntryToIndex<SeededNumberDictionary>( 3615 Node* details_index = EntryToIndex<SeededNumberDictionary>(
3608 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex); 3616 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex);
3609 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index)); 3617 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index));
3610 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); 3618 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details);
3611 // TODO(jkummerow): Support accessors without missing? 3619 // TODO(jkummerow): Support accessors without missing?
3612 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss); 3620 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss);
3613 // Finally, load the value. 3621 // Finally, load the value.
3614 Node* value_index = EntryToIndex<SeededNumberDictionary>( 3622 Node* value_index = EntryToIndex<SeededNumberDictionary>(
3615 var_entry.value(), SeededNumberDictionary::kEntryValueIndex); 3623 var_entry.value(), SeededNumberDictionary::kEntryValueIndex);
3616 Return(LoadFixedArrayElement(elements, value_index)); 3624 Return(LoadFixedArrayElement(elements, value_index));
3617 } 3625 }
3618 3626
3619 Bind(&if_typed_array); 3627 Bind(&if_typed_array);
3620 { 3628 {
3621 Comment("typed elements"); 3629 Comment("typed elements");
3622 // Check if buffer has been neutered. 3630 // Check if buffer has been neutered.
3623 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); 3631 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
3624 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, 3632 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
3625 MachineType::Uint32()); 3633 MachineType::Uint32());
3626 Node* neutered_bit = 3634 Node* neutered_bit =
3627 Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask)); 3635 Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask));
3628 GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), miss); 3636 GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), miss);
3629 3637
3630 // Bounds check. 3638 // Bounds check.
3631 Node* length = 3639 Node* length =
3632 SmiUntag(LoadObjectField(object, JSTypedArray::kLengthOffset)); 3640 SmiUntag(LoadObjectField(object, JSTypedArray::kLengthOffset));
3633 GotoUnless(UintPtrLessThan(key, length), out_of_bounds); 3641 GotoUnless(UintPtrLessThan(intptr_index, length), out_of_bounds);
3634 3642
3635 // Backing store = external_pointer + base_pointer. 3643 // Backing store = external_pointer + base_pointer.
3636 Node* external_pointer = 3644 Node* external_pointer =
3637 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, 3645 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
3638 MachineType::Pointer()); 3646 MachineType::Pointer());
3639 Node* base_pointer = 3647 Node* base_pointer =
3640 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); 3648 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
3641 Node* backing_store = IntPtrAdd(external_pointer, base_pointer); 3649 Node* backing_store = IntPtrAdd(external_pointer, base_pointer);
3642 3650
3643 Label uint8_elements(this), int8_elements(this), uint16_elements(this), 3651 Label uint8_elements(this), int8_elements(this), uint16_elements(this),
(...skipping 10 matching lines...) Expand all
3654 const int kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND - 3662 const int kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
3655 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND + 3663 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
3656 1; 3664 1;
3657 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds)); 3665 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds));
3658 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels)); 3666 DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels));
3659 Switch(elements_kind, miss, elements_kinds, elements_kind_labels, 3667 Switch(elements_kind, miss, elements_kinds, elements_kind_labels,
3660 static_cast<size_t>(kTypedElementsKindCount)); 3668 static_cast<size_t>(kTypedElementsKindCount));
3661 Bind(&uint8_elements); 3669 Bind(&uint8_elements);
3662 { 3670 {
3663 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. 3671 Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too.
3664 Return(SmiTag(Load(MachineType::Uint8(), backing_store, key))); 3672 Return(SmiTag(Load(MachineType::Uint8(), backing_store, intptr_index)));
3665 } 3673 }
3666 Bind(&int8_elements); 3674 Bind(&int8_elements);
3667 { 3675 {
3668 Comment("INT8_ELEMENTS"); 3676 Comment("INT8_ELEMENTS");
3669 Return(SmiTag(Load(MachineType::Int8(), backing_store, key))); 3677 Return(SmiTag(Load(MachineType::Int8(), backing_store, intptr_index)));
3670 } 3678 }
3671 Bind(&uint16_elements); 3679 Bind(&uint16_elements);
3672 { 3680 {
3673 Comment("UINT16_ELEMENTS"); 3681 Comment("UINT16_ELEMENTS");
3674 Node* index = WordShl(key, IntPtrConstant(1)); 3682 Node* index = WordShl(intptr_index, IntPtrConstant(1));
3675 Return(SmiTag(Load(MachineType::Uint16(), backing_store, index))); 3683 Return(SmiTag(Load(MachineType::Uint16(), backing_store, index)));
3676 } 3684 }
3677 Bind(&int16_elements); 3685 Bind(&int16_elements);
3678 { 3686 {
3679 Comment("INT16_ELEMENTS"); 3687 Comment("INT16_ELEMENTS");
3680 Node* index = WordShl(key, IntPtrConstant(1)); 3688 Node* index = WordShl(intptr_index, IntPtrConstant(1));
3681 Return(SmiTag(Load(MachineType::Int16(), backing_store, index))); 3689 Return(SmiTag(Load(MachineType::Int16(), backing_store, index)));
3682 } 3690 }
3683 Bind(&uint32_elements); 3691 Bind(&uint32_elements);
3684 { 3692 {
3685 Comment("UINT32_ELEMENTS"); 3693 Comment("UINT32_ELEMENTS");
3686 Node* index = WordShl(key, IntPtrConstant(2)); 3694 Node* index = WordShl(intptr_index, IntPtrConstant(2));
3687 Node* element = Load(MachineType::Uint32(), backing_store, index); 3695 Node* element = Load(MachineType::Uint32(), backing_store, index);
3688 Return(ChangeUint32ToTagged(element)); 3696 Return(ChangeUint32ToTagged(element));
3689 } 3697 }
3690 Bind(&int32_elements); 3698 Bind(&int32_elements);
3691 { 3699 {
3692 Comment("INT32_ELEMENTS"); 3700 Comment("INT32_ELEMENTS");
3693 Node* index = WordShl(key, IntPtrConstant(2)); 3701 Node* index = WordShl(intptr_index, IntPtrConstant(2));
3694 Node* element = Load(MachineType::Int32(), backing_store, index); 3702 Node* element = Load(MachineType::Int32(), backing_store, index);
3695 Return(ChangeInt32ToTagged(element)); 3703 Return(ChangeInt32ToTagged(element));
3696 } 3704 }
3697 Bind(&float32_elements); 3705 Bind(&float32_elements);
3698 { 3706 {
3699 Comment("FLOAT32_ELEMENTS"); 3707 Comment("FLOAT32_ELEMENTS");
3700 Node* index = WordShl(key, IntPtrConstant(2)); 3708 Node* index = WordShl(intptr_index, IntPtrConstant(2));
3701 Node* element = Load(MachineType::Float32(), backing_store, index); 3709 Node* element = Load(MachineType::Float32(), backing_store, index);
3702 var_double_value->Bind(ChangeFloat32ToFloat64(element)); 3710 var_double_value->Bind(ChangeFloat32ToFloat64(element));
3703 Goto(rebox_double); 3711 Goto(rebox_double);
3704 } 3712 }
3705 Bind(&float64_elements); 3713 Bind(&float64_elements);
3706 { 3714 {
3707 Comment("FLOAT64_ELEMENTS"); 3715 Comment("FLOAT64_ELEMENTS");
3708 Node* index = WordShl(key, IntPtrConstant(3)); 3716 Node* index = WordShl(intptr_index, IntPtrConstant(3));
3709 Node* element = Load(MachineType::Float64(), backing_store, index); 3717 Node* element = Load(MachineType::Float64(), backing_store, index);
3710 var_double_value->Bind(element); 3718 var_double_value->Bind(element);
3711 Goto(rebox_double); 3719 Goto(rebox_double);
3712 } 3720 }
3713 } 3721 }
3714 } 3722 }
3715 3723
3716 void CodeStubAssembler::HandleLoadICHandlerCase( 3724 void CodeStubAssembler::HandleLoadICHandlerCase(
3717 const LoadICParameters* p, Node* handler, Label* miss, 3725 const LoadICParameters* p, Node* handler, Label* miss,
3718 ElementSupport support_elements) { 3726 ElementSupport support_elements) {
(...skipping 10 matching lines...) Expand all
3729 Node* handler_word = SmiUntag(handler); 3737 Node* handler_word = SmiUntag(handler);
3730 if (support_elements == kSupportElements) { 3738 if (support_elements == kSupportElements) {
3731 Label property(this); 3739 Label property(this);
3732 Node* handler_type = 3740 Node* handler_type =
3733 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBit::kMask)); 3741 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBit::kMask));
3734 GotoUnless( 3742 GotoUnless(
3735 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)), 3743 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)),
3736 &property); 3744 &property);
3737 3745
3738 Comment("element_load"); 3746 Comment("element_load");
3739 Node* key = TryToIntptr(p->name, miss); 3747 Node* intptr_index = TryToIntptr(p->name, miss);
3740 Node* elements = LoadElements(p->receiver); 3748 Node* elements = LoadElements(p->receiver);
3741 Node* is_jsarray = 3749 Node* is_jsarray =
3742 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask)); 3750 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask));
3743 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0)); 3751 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0));
3744 Node* elements_kind = BitFieldDecode<KeyedLoadElementsKind>(handler_word); 3752 Node* elements_kind = BitFieldDecode<KeyedLoadElementsKind>(handler_word);
3745 Label if_hole(this), unimplemented_elements_kind(this); 3753 Label if_hole(this), unimplemented_elements_kind(this);
3746 Label* out_of_bounds = miss; 3754 Label* out_of_bounds = miss;
3747 EmitElementLoad(p->receiver, elements, elements_kind, key, 3755 EmitElementLoad(p->receiver, elements, elements_kind, intptr_index,
3748 is_jsarray_condition, &if_hole, &rebox_double, 3756 is_jsarray_condition, &if_hole, &rebox_double,
3749 &var_double_value, &unimplemented_elements_kind, 3757 &var_double_value, &unimplemented_elements_kind,
3750 out_of_bounds, miss); 3758 out_of_bounds, miss);
3751 3759
3752 Bind(&unimplemented_elements_kind); 3760 Bind(&unimplemented_elements_kind);
3753 { 3761 {
3754 // Smi handlers should only be installed for supported elements kinds. 3762 // Smi handlers should only be installed for supported elements kinds.
3755 // Crash if we get here. 3763 // Crash if we get here.
3756 DebugBreak(); 3764 DebugBreak();
3757 Goto(miss); 3765 Goto(miss);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3929 Bind(&miss); 3937 Bind(&miss);
3930 { 3938 {
3931 Comment("KeyedLoadIC_miss"); 3939 Comment("KeyedLoadIC_miss");
3932 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, 3940 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver,
3933 p->name, p->slot, p->vector); 3941 p->name, p->slot, p->vector);
3934 } 3942 }
3935 } 3943 }
3936 3944
3937 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { 3945 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
3938 Variable var_index(this, MachineType::PointerRepresentation()); 3946 Variable var_index(this, MachineType::PointerRepresentation());
3939 Label if_index(this), if_key_is_not_number(this), if_index_name(this), 3947 Label if_index(this), if_unique_name(this), if_element_hole(this),
3940 if_unique_name(this), if_element_hole(this), if_oob(this), slow(this), 3948 if_oob(this), slow(this), stub_cache_miss(this),
3941 stub_cache_miss(this), if_property_dictionary(this); 3949 if_property_dictionary(this);
3942 3950
3943 Node* receiver = p->receiver; 3951 Node* receiver = p->receiver;
3944 GotoIf(WordIsSmi(receiver), &slow); 3952 GotoIf(WordIsSmi(receiver), &slow);
3945 Node* receiver_map = LoadMap(receiver); 3953 Node* receiver_map = LoadMap(receiver);
3946 Node* instance_type = LoadMapInstanceType(receiver_map); 3954 Node* instance_type = LoadMapInstanceType(receiver_map);
3947 // Receivers requiring non-standard element accesses (interceptors, access 3955 // Receivers requiring non-standard element accesses (interceptors, access
3948 // checks, strings and string wrappers, proxies) are handled in the runtime. 3956 // checks, strings and string wrappers, proxies) are handled in the runtime.
3949 GotoIf(Int32LessThanOrEqual(instance_type, 3957 GotoIf(Int32LessThanOrEqual(instance_type,
3950 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), 3958 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
3951 &slow); 3959 &slow);
3952 3960
3953 // Check what kind of key we have.
3954 Node* key = p->name; 3961 Node* key = p->name;
3955 var_index.Bind(TryToIntptr(key, &if_key_is_not_number)); 3962 TryToName(key, &if_index, &var_index, &if_unique_name, &slow);
3956 Goto(&if_index);
3957
3958 Node* hash = nullptr;
3959 // TODO(jkummerow): Unify this with CodeStubAssembler::TryToName().
3960 Bind(&if_key_is_not_number);
3961 {
3962 Node* key_map = LoadMap(key);
3963 Node* key_instance_type = LoadMapInstanceType(key_map);
3964 // Jump to the runtime if key is neither String nor Symbol.
3965 GotoIf(Int32GreaterThan(key_instance_type,
3966 Int32Constant(LAST_UNIQUE_NAME_TYPE)),
3967 &slow);
3968 // Symbols are always unique names.
3969 GotoIf(Word32Equal(key_instance_type, Int32Constant(LAST_UNIQUE_NAME_TYPE)),
3970 &if_unique_name);
3971 // |key| is a String. Check if it has a cached array index.
3972 hash = LoadNameHashField(key);
3973 Node* contains_index =
3974 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
3975 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_index_name);
3976 // Otherwise, jump to the runtime if the string is not internalized.
3977 STATIC_ASSERT(kNotInternalizedTag != 0);
3978 Node* not_internalized =
3979 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
3980 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), &slow);
3981 Goto(&if_unique_name);
3982 }
3983
3984 Bind(&if_index_name);
3985 {
3986 Comment("string key with cached array index");
3987 var_index.Bind(BitFieldDecode<String::ArrayIndexValueBits>(hash));
3988 Goto(&if_index);
3989 }
3990 3963
3991 Bind(&if_index); 3964 Bind(&if_index);
3992 { 3965 {
3993 Comment("integer index"); 3966 Comment("integer index");
3994 Node* index = var_index.value(); 3967 Node* index = var_index.value();
3995 Node* elements = LoadElements(receiver); 3968 Node* elements = LoadElements(receiver);
3996 Node* bitfield2 = LoadMapBitField2(receiver_map); 3969 Node* bitfield2 = LoadMapBitField2(receiver_map);
3997 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bitfield2); 3970 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bitfield2);
3998 Node* is_jsarray_condition = 3971 Node* is_jsarray_condition =
3999 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); 3972 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
4212 Heap::kTheHoleValueRootIndex); 4185 Heap::kTheHoleValueRootIndex);
4213 4186
4214 // Store the WeakCell in the feedback vector. 4187 // Store the WeakCell in the feedback vector.
4215 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 4188 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
4216 CodeStubAssembler::SMI_PARAMETERS); 4189 CodeStubAssembler::SMI_PARAMETERS);
4217 return cell; 4190 return cell;
4218 } 4191 }
4219 4192
4220 } // namespace internal 4193 } // namespace internal
4221 } // namespace v8 4194 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698