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

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

Issue 2277363002: [stubs] Consolidate TryToName implementation (Closed)
Patch Set: 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
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 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 } 2249 }
2250 } 2250 }
2251 2251
2252 void CodeStubAssembler::Use(Label* label) { 2252 void CodeStubAssembler::Use(Label* label) {
2253 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); 2253 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
2254 } 2254 }
2255 2255
2256 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, 2256 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
2257 Variable* var_index, Label* if_keyisunique, 2257 Variable* var_index, Label* if_keyisunique,
2258 Label* if_bailout) { 2258 Label* if_bailout) {
2259 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); 2259 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep());
2260 Comment("TryToName"); 2260 Comment("TryToName");
2261 2261
2262 Label if_keyissmi(this), if_keyisnotsmi(this); 2262 Label if_hascachedindex(this), if_keyisnotindex(this);
2263 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); 2263 // Handle Smi and HeapNumber keys.
2264 Bind(&if_keyissmi); 2264 var_index->Bind(TryToIntptr(key, &if_keyisnotindex));
2265 { 2265 Goto(if_keyisindex);
2266 // Negative smi keys are named properties. Handle in the runtime.
2267 GotoUnless(WordIsPositiveSmi(key), if_bailout);
2268 2266
2269 var_index->Bind(SmiToWord32(key)); 2267 Bind(&if_keyisnotindex);
2270 Goto(if_keyisindex);
2271 }
2272
2273 Bind(&if_keyisnotsmi);
2274
2275 Node* key_instance_type = LoadInstanceType(key); 2268 Node* key_instance_type = LoadInstanceType(key);
2276 // Symbols are unique. 2269 // Symbols are unique.
2277 GotoIf(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)), 2270 GotoIf(Word32Equal(key_instance_type, Int32Constant(SYMBOL_TYPE)),
2278 if_keyisunique); 2271 if_keyisunique);
2272 // Miss if |key| is not a String.
2273 GotoIf(
2274 Int32GreaterThan(key_instance_type, Int32Constant(LAST_UNIQUE_NAME_TYPE)),
Igor Sheludko 2016/09/01 14:31:30 It looks like we are missing FIRST_STRING_TYPE and
Jakob Kummerow 2016/09/05 13:15:54 Done.
2275 if_bailout);
2276 // |key| is a String. Check if it has a cached array index.
2277 Node* hash = LoadNameHashField(key);
2278 Node* contains_index =
2279 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
2280 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex);
Igor Sheludko 2016/09/01 14:31:30 What if the hash field is not computed yet? We can
Igor Sheludko 2016/09/01 15:52:17 Ignore this comment. We set the hash field of a ne
Jakob Kummerow 2016/09/05 13:15:54 Acknowledged. It's also what the handwritten Keyed
2281 // No cached array index; check if |key| is internalized.
2282 STATIC_ASSERT(kNotInternalizedTag != 0);
2283 Node* not_internalized =
2284 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
2285 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout);
2286 Goto(if_keyisunique);
2279 2287
2280 Label if_keyisinternalized(this); 2288 Bind(&if_hascachedindex);
2281 Node* bits =
2282 WordAnd(key_instance_type,
2283 Int32Constant(kIsNotStringMask | kIsNotInternalizedMask));
2284 Branch(Word32Equal(bits, Int32Constant(kStringTag | kInternalizedTag)),
2285 &if_keyisinternalized, if_bailout);
2286 Bind(&if_keyisinternalized);
2287
2288 // Check whether the key is an array index passed in as string. Handle
2289 // uniform with smi keys if so.
2290 // TODO(verwaest): Also support non-internalized strings.
2291 Node* hash = LoadNameHashField(key);
2292 Node* bit = Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
2293 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_keyisunique);
2294 // Key is an index. Check if it is small enough to be encoded in the
2295 // hash_field. Handle too big array index in runtime.
2296 bit = Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
2297 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_bailout);
2298 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); 2289 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash));
2299 Goto(if_keyisindex); 2290 Goto(if_keyisindex);
2300 } 2291 }
2301 2292
2302 template <typename Dictionary> 2293 template <typename Dictionary>
2303 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { 2294 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
2304 Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize)); 2295 Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize));
2305 return Int32Add(entry_index, 2296 return Int32Add(entry_index,
2306 Int32Constant(Dictionary::kElementsStartIndex + field_index)); 2297 Int32Constant(Dictionary::kElementsStartIndex + field_index));
2307 } 2298 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 Word32Shl(hash, Int32Constant(15))); 2372 Word32Shl(hash, Int32Constant(15)));
2382 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12))); 2373 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
2383 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2))); 2374 hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2)));
2384 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4))); 2375 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4)));
2385 hash = Int32Mul(hash, Int32Constant(2057)); 2376 hash = Int32Mul(hash, Int32Constant(2057));
2386 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); 2377 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
2387 return Word32And(hash, Int32Constant(0x3fffffff)); 2378 return Word32And(hash, Int32Constant(0x3fffffff));
2388 } 2379 }
2389 2380
2390 template <typename Dictionary> 2381 template <typename Dictionary>
2391 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key, 2382 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key,
Igor Sheludko 2016/09/01 14:31:30 Please rename |key| -> |intptr_index| for readabil
Jakob Kummerow 2016/09/05 13:15:54 Done.
2392 Label* if_found, 2383 Label* if_found,
2393 Variable* var_entry, 2384 Variable* var_entry,
2394 Label* if_not_found) { 2385 Label* if_not_found) {
2395 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep()); 2386 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep());
2396 Comment("NumberDictionaryLookup"); 2387 Comment("NumberDictionaryLookup");
2397 2388
2398 Node* capacity = LoadAndUntagToWord32FixedArrayElement( 2389 Node* capacity = LoadAndUntagToWord32FixedArrayElement(
2399 dictionary, Int32Constant(Dictionary::kCapacityIndex)); 2390 dictionary, Int32Constant(Dictionary::kCapacityIndex));
2400 Node* mask = Int32Sub(capacity, Int32Constant(1)); 2391 Node* mask = Int32Sub(capacity, Int32Constant(1));
2401 2392
2402 Node* seed; 2393 Node* seed;
2403 if (Dictionary::ShapeT::UsesSeed) { 2394 if (Dictionary::ShapeT::UsesSeed) {
2404 seed = HashSeed(); 2395 seed = HashSeed();
2405 } else { 2396 } else {
2406 seed = Int32Constant(kZeroHashSeed); 2397 seed = Int32Constant(kZeroHashSeed);
2407 } 2398 }
2408 Node* hash = ComputeIntegerHash(key, seed); 2399 Node* hash = ComputeIntegerHash(key, seed);
2409 Node* key_as_float64 = ChangeUint32ToFloat64(key); 2400 Node* key_as_float64 = RoundIntPtrToFloat64(key);
2410 2401
2411 // See Dictionary::FirstProbe(). 2402 // See Dictionary::FirstProbe().
2412 Node* count = Int32Constant(0); 2403 Node* count = Int32Constant(0);
2413 Node* entry = Word32And(hash, mask); 2404 Node* entry = Word32And(hash, mask);
2414 2405
2415 Node* undefined = UndefinedConstant(); 2406 Node* undefined = UndefinedConstant();
2416 Node* the_hole = TheHoleConstant(); 2407 Node* the_hole = TheHoleConstant();
2417 2408
2418 Variable var_count(this, MachineRepresentation::kWord32); 2409 Variable var_count(this, MachineRepresentation::kWord32);
2419 Variable* loop_vars[] = {&var_count, var_entry}; 2410 Variable* loop_vars[] = {&var_count, var_entry};
2420 Label loop(this, 2, loop_vars); 2411 Label loop(this, 2, loop_vars);
2421 var_count.Bind(count); 2412 var_count.Bind(count);
2422 var_entry->Bind(entry); 2413 var_entry->Bind(entry);
2423 Goto(&loop); 2414 Goto(&loop);
2424 Bind(&loop); 2415 Bind(&loop);
2425 { 2416 {
2426 Node* count = var_count.value(); 2417 Node* count = var_count.value();
2427 Node* entry = var_entry->value(); 2418 Node* entry = var_entry->value();
2428 2419
2429 Node* index = EntryToIndex<Dictionary>(entry); 2420 Node* index = EntryToIndex<Dictionary>(entry);
2430 Node* current = LoadFixedArrayElement(dictionary, index); 2421 Node* current = LoadFixedArrayElement(dictionary, index);
2431 GotoIf(WordEqual(current, undefined), if_not_found); 2422 GotoIf(WordEqual(current, undefined), if_not_found);
2432 Label next_probe(this); 2423 Label next_probe(this);
2433 { 2424 {
2434 Label if_currentissmi(this), if_currentisnotsmi(this); 2425 Label if_currentissmi(this), if_currentisnotsmi(this);
2435 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); 2426 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi);
2436 Bind(&if_currentissmi); 2427 Bind(&if_currentissmi);
2437 { 2428 {
2438 Node* current_value = SmiToWord32(current); 2429 Node* current_value = SmiUntag(current);
2439 Branch(Word32Equal(current_value, key), if_found, &next_probe); 2430 Branch(WordEqual(current_value, key), if_found, &next_probe);
2440 } 2431 }
2441 Bind(&if_currentisnotsmi); 2432 Bind(&if_currentisnotsmi);
2442 { 2433 {
2443 GotoIf(WordEqual(current, the_hole), &next_probe); 2434 GotoIf(WordEqual(current, the_hole), &next_probe);
2444 // Current must be the Number. 2435 // Current must be the Number.
2445 Node* current_value = LoadHeapNumberValue(current); 2436 Node* current_value = LoadHeapNumberValue(current);
2446 Branch(Float64Equal(current_value, key_as_float64), if_found, 2437 Branch(Float64Equal(current_value, key_as_float64), if_found,
2447 &next_probe); 2438 &next_probe);
2448 } 2439 }
2449 } 2440 }
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2809 // Call the accessor. 2800 // Call the accessor.
2810 Callable callable = CodeFactory::Call(isolate()); 2801 Callable callable = CodeFactory::Call(isolate());
2811 Node* result = CallJS(callable, context, getter, receiver); 2802 Node* result = CallJS(callable, context, getter, receiver);
2812 var_value->Bind(result); 2803 var_value->Bind(result);
2813 Goto(if_found_value); 2804 Goto(if_found_value);
2814 } 2805 }
2815 } 2806 }
2816 } 2807 }
2817 2808
2818 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, 2809 void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
2819 Node* instance_type, Node* index, 2810 Node* instance_type, Node* index,
Igor Sheludko 2016/09/01 14:31:30 Please rename |index| -> |intptr_index| for readab
Jakob Kummerow 2016/09/05 13:15:53 Done.
2820 Label* if_found, Label* if_not_found, 2811 Label* if_found, Label* if_not_found,
2821 Label* if_bailout) { 2812 Label* if_bailout) {
2822 // Handle special objects in runtime. 2813 // Handle special objects in runtime.
2823 GotoIf(Int32LessThanOrEqual(instance_type, 2814 GotoIf(Int32LessThanOrEqual(instance_type,
2824 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 2815 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
2825 if_bailout); 2816 if_bailout);
2826 2817
2827 Node* bit_field2 = LoadMapBitField2(map); 2818 Node* bit_field2 = LoadMapBitField2(map);
2828 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2); 2819 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2);
2829 2820
2830 // TODO(verwaest): Support other elements kinds as well. 2821 // TODO(verwaest): Support other elements kinds as well.
2831 Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this), 2822 Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this),
2832 if_isfaststringwrapper(this), if_isslowstringwrapper(this); 2823 if_isfaststringwrapper(this), if_isslowstringwrapper(this), if_oob(this);
2833 // clang-format off 2824 // clang-format off
2834 int32_t values[] = { 2825 int32_t values[] = {
2835 // Handled by {if_isobjectorsmi}. 2826 // Handled by {if_isobjectorsmi}.
2836 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, 2827 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
2837 FAST_HOLEY_ELEMENTS, 2828 FAST_HOLEY_ELEMENTS,
2838 // Handled by {if_isdouble}. 2829 // Handled by {if_isdouble}.
2839 FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, 2830 FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
2840 // Handled by {if_isdictionary}. 2831 // Handled by {if_isdictionary}.
2841 DICTIONARY_ELEMENTS, 2832 DICTIONARY_ELEMENTS,
2842 // Handled by {if_isfaststringwrapper}. 2833 // Handled by {if_isfaststringwrapper}.
(...skipping 14 matching lines...) Expand all
2857 }; 2848 };
2858 // clang-format on 2849 // clang-format on
2859 STATIC_ASSERT(arraysize(values) == arraysize(labels)); 2850 STATIC_ASSERT(arraysize(values) == arraysize(labels));
2860 Switch(elements_kind, if_bailout, values, labels, arraysize(values)); 2851 Switch(elements_kind, if_bailout, values, labels, arraysize(values));
2861 2852
2862 Bind(&if_isobjectorsmi); 2853 Bind(&if_isobjectorsmi);
2863 { 2854 {
2864 Node* elements = LoadElements(object); 2855 Node* elements = LoadElements(object);
2865 Node* length = LoadAndUntagFixedArrayBaseLength(elements); 2856 Node* length = LoadAndUntagFixedArrayBaseLength(elements);
2866 2857
2867 GotoUnless(Uint32LessThan(index, length), if_not_found); 2858 GotoUnless(UintPtrLessThan(index, length), &if_oob);
2868 2859
2869 Node* element = LoadFixedArrayElement(elements, index); 2860 Node* element =
2861 LoadFixedArrayElement(elements, index, 0, INTPTR_PARAMETERS);
2870 Node* the_hole = TheHoleConstant(); 2862 Node* the_hole = TheHoleConstant();
2871 Branch(WordEqual(element, the_hole), if_not_found, if_found); 2863 Branch(WordEqual(element, the_hole), if_not_found, if_found);
2872 } 2864 }
2873 Bind(&if_isdouble); 2865 Bind(&if_isdouble);
2874 { 2866 {
2875 Node* elements = LoadElements(object); 2867 Node* elements = LoadElements(object);
2876 Node* length = LoadAndUntagFixedArrayBaseLength(elements); 2868 Node* length = LoadAndUntagFixedArrayBaseLength(elements);
2877 2869
2878 GotoUnless(Uint32LessThan(index, length), if_not_found); 2870 GotoUnless(UintPtrLessThan(index, length), &if_oob);
2879 2871
2880 if (kPointerSize == kDoubleSize) { 2872 if (kPointerSize == kDoubleSize) {
2881 Node* element = 2873 Node* element = LoadFixedDoubleArrayElement(
2882 LoadFixedDoubleArrayElement(elements, index, MachineType::Uint64()); 2874 elements, index, MachineType::Uint64(), 0, INTPTR_PARAMETERS);
2883 Node* the_hole = Int64Constant(kHoleNanInt64); 2875 Node* the_hole = Int64Constant(kHoleNanInt64);
2884 Branch(Word64Equal(element, the_hole), if_not_found, if_found); 2876 Branch(Word64Equal(element, the_hole), if_not_found, if_found);
2885 } else { 2877 } else {
2886 Node* element_upper = 2878 Node* element_upper = LoadFixedDoubleArrayElement(
2887 LoadFixedDoubleArrayElement(elements, index, MachineType::Uint32(), 2879 elements, index, MachineType::Uint32(), kIeeeDoubleExponentWordOffset,
2888 kIeeeDoubleExponentWordOffset); 2880 INTPTR_PARAMETERS);
2889 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), 2881 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
2890 if_not_found, if_found); 2882 if_not_found, if_found);
2891 } 2883 }
2892 } 2884 }
2893 Bind(&if_isdictionary); 2885 Bind(&if_isdictionary);
2894 { 2886 {
2895 Variable var_entry(this, MachineRepresentation::kWord32); 2887 Variable var_entry(this, MachineRepresentation::kWord32);
2896 Node* elements = LoadElements(object); 2888 Node* elements = LoadElements(object);
2897 NumberDictionaryLookup<SeededNumberDictionary>(elements, index, if_found, 2889 NumberDictionaryLookup<SeededNumberDictionary>(elements, index, if_found,
2898 &var_entry, if_not_found); 2890 &var_entry, if_not_found);
2899 } 2891 }
2900 Bind(&if_isfaststringwrapper); 2892 Bind(&if_isfaststringwrapper);
2901 { 2893 {
2902 AssertInstanceType(object, JS_VALUE_TYPE); 2894 AssertInstanceType(object, JS_VALUE_TYPE);
2903 Node* string = LoadJSValueValue(object); 2895 Node* string = LoadJSValueValue(object);
2904 Assert(Int32LessThan(LoadInstanceType(string), 2896 Assert(Int32LessThan(LoadInstanceType(string),
2905 Int32Constant(FIRST_NONSTRING_TYPE))); 2897 Int32Constant(FIRST_NONSTRING_TYPE)));
2906 Node* length = LoadStringLength(string); 2898 Node* length = LoadStringLength(string);
2907 GotoIf(Uint32LessThan(index, SmiToWord32(length)), if_found); 2899 GotoIf(UintPtrLessThan(index, SmiUntag(length)), if_found);
2908 Goto(&if_isobjectorsmi); 2900 Goto(&if_isobjectorsmi);
2909 } 2901 }
2910 Bind(&if_isslowstringwrapper); 2902 Bind(&if_isslowstringwrapper);
2911 { 2903 {
2912 AssertInstanceType(object, JS_VALUE_TYPE); 2904 AssertInstanceType(object, JS_VALUE_TYPE);
2913 Node* string = LoadJSValueValue(object); 2905 Node* string = LoadJSValueValue(object);
2914 Assert(Int32LessThan(LoadInstanceType(string), 2906 Assert(Int32LessThan(LoadInstanceType(string),
2915 Int32Constant(FIRST_NONSTRING_TYPE))); 2907 Int32Constant(FIRST_NONSTRING_TYPE)));
2916 Node* length = LoadStringLength(string); 2908 Node* length = LoadStringLength(string);
2917 GotoIf(Uint32LessThan(index, SmiToWord32(length)), if_found); 2909 GotoIf(UintPtrLessThan(index, SmiUntag(length)), if_found);
2918 Goto(&if_isdictionary); 2910 Goto(&if_isdictionary);
2919 } 2911 }
2912 Bind(&if_oob);
2913 {
2914 // Positive OOB indices mean "not found", negative indices must be
2915 // converted to property names.
2916 GotoIf(IntPtrLessThan(index, IntPtrConstant(0)), if_bailout);
2917 Goto(if_not_found);
2918 }
2920 } 2919 }
2921 2920
2922 // Instantiate template methods to workaround GCC compilation issue. 2921 // Instantiate template methods to workaround GCC compilation issue.
2923 template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>( 2922 template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>(
2924 Node*, Node*, Label*, Variable*, Label*); 2923 Node*, Node*, Label*, Variable*, Label*);
2925 template void CodeStubAssembler::NumberDictionaryLookup< 2924 template void CodeStubAssembler::NumberDictionaryLookup<
2926 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); 2925 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*);
2927 2926
2928 void CodeStubAssembler::TryPrototypeChainLookup( 2927 void CodeStubAssembler::TryPrototypeChainLookup(
2929 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder, 2928 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder,
2930 LookupInHolder& lookup_element_in_holder, Label* if_end, 2929 LookupInHolder& lookup_element_in_holder, Label* if_end,
2931 Label* if_bailout) { 2930 Label* if_bailout) {
2932 // Ensure receiver is JSReceiver, otherwise bailout. 2931 // Ensure receiver is JSReceiver, otherwise bailout.
2933 Label if_objectisnotsmi(this); 2932 Label if_objectisnotsmi(this);
2934 Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi); 2933 Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi);
2935 Bind(&if_objectisnotsmi); 2934 Bind(&if_objectisnotsmi);
2936 2935
2937 Node* map = LoadMap(receiver); 2936 Node* map = LoadMap(receiver);
2938 Node* instance_type = LoadMapInstanceType(map); 2937 Node* instance_type = LoadMapInstanceType(map);
2939 { 2938 {
2940 Label if_objectisreceiver(this); 2939 Label if_objectisreceiver(this);
2941 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 2940 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2942 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); 2941 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE);
2943 Branch( 2942 Branch(
2944 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), 2943 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)),
2945 &if_objectisreceiver, if_bailout); 2944 &if_objectisreceiver, if_bailout);
2946 Bind(&if_objectisreceiver); 2945 Bind(&if_objectisreceiver);
2947 } 2946 }
2948 2947
2949 Variable var_index(this, MachineRepresentation::kWord32); 2948 Variable var_index(this, MachineType::PointerRepresentation());
2950 2949
2951 Label if_keyisindex(this), if_iskeyunique(this); 2950 Label if_keyisindex(this), if_iskeyunique(this);
2952 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); 2951 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout);
2953 2952
2954 Bind(&if_iskeyunique); 2953 Bind(&if_iskeyunique);
2955 { 2954 {
2956 Variable var_holder(this, MachineRepresentation::kTagged); 2955 Variable var_holder(this, MachineRepresentation::kTagged);
2957 Variable var_holder_map(this, MachineRepresentation::kTagged); 2956 Variable var_holder_map(this, MachineRepresentation::kTagged);
2958 Variable var_holder_instance_type(this, MachineRepresentation::kWord8); 2957 Variable var_holder_instance_type(this, MachineRepresentation::kWord8);
2959 2958
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 } 3170 }
3172 3171
3173 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, 3172 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
3174 ElementsKind kind, 3173 ElementsKind kind,
3175 ParameterMode mode, 3174 ParameterMode mode,
3176 int base_size) { 3175 int base_size) {
3177 bool is_double = IsFastDoubleElementsKind(kind); 3176 bool is_double = IsFastDoubleElementsKind(kind);
3178 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2; 3177 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2;
3179 int element_size = 1 << element_size_shift; 3178 int element_size = 1 << element_size_shift;
3180 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; 3179 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize;
3181 int32_t index = 0; 3180 intptr_t index = 0;
3182 bool constant_index = false; 3181 bool constant_index = false;
3183 if (mode == SMI_PARAMETERS) { 3182 if (mode == SMI_PARAMETERS) {
3184 element_size_shift -= kSmiShiftBits; 3183 element_size_shift -= kSmiShiftBits;
3185 intptr_t temp = 0; 3184 constant_index = ToIntPtrConstant(index_node, index);
3186 constant_index = ToIntPtrConstant(index_node, temp); 3185 index = index >> kSmiShiftBits;
3187 index = temp >> kSmiShiftBits; 3186 } else if (mode == INTEGER_PARAMETERS) {
3187 int32_t temp = 0;
3188 constant_index = ToInt32Constant(index_node, temp);
3189 index = static_cast<intptr_t>(temp);
3188 } else { 3190 } else {
3189 constant_index = ToInt32Constant(index_node, index); 3191 DCHECK(mode == INTPTR_PARAMETERS);
3192 constant_index = ToIntPtrConstant(index_node, index);
3190 } 3193 }
3191 if (constant_index) { 3194 if (constant_index) {
3192 return IntPtrConstant(base_size + element_size * index); 3195 return IntPtrConstant(base_size + element_size * index);
3193 } 3196 }
3194 if (Is64() && mode == INTEGER_PARAMETERS) { 3197 if (Is64() && mode == INTEGER_PARAMETERS) {
3195 index_node = ChangeInt32ToInt64(index_node); 3198 index_node = ChangeInt32ToInt64(index_node);
3196 } 3199 }
3197 if (base_size == 0) { 3200 if (base_size == 0) {
3198 return (element_size_shift >= 0) 3201 return (element_size_shift >= 0)
3199 ? WordShl(index_node, IntPtrConstant(element_size_shift)) 3202 ? WordShl(index_node, IntPtrConstant(element_size_shift))
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3494 } 3497 }
3495 Bind(&if_array); 3498 Bind(&if_array);
3496 { 3499 {
3497 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset))); 3500 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset)));
3498 Goto(&length_loaded); 3501 Goto(&length_loaded);
3499 } 3502 }
3500 Bind(&length_loaded); 3503 Bind(&length_loaded);
3501 GotoUnless(UintPtrLessThan(intptr_key, var_length.value()), miss); 3504 GotoUnless(UintPtrLessThan(intptr_key, var_length.value()), miss);
3502 } 3505 }
3503 3506
3504 // |key| should be untagged (int32). 3507 // |key| should be untagged (int32).
Igor Sheludko 2016/09/01 14:31:30 How about renaming |key| to |intptr_index| for rea
Jakob Kummerow 2016/09/05 13:15:53 Done.
3505 void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, 3508 void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements,
3506 Node* elements_kind, Node* key, 3509 Node* elements_kind, Node* key,
3507 Node* is_jsarray_condition, 3510 Node* is_jsarray_condition,
3508 Label* if_hole, Label* rebox_double, 3511 Label* if_hole, Label* rebox_double,
3509 Variable* var_double_value, 3512 Variable* var_double_value,
3510 Label* unimplemented_elements_kind, 3513 Label* unimplemented_elements_kind,
3511 Label* out_of_bounds, Label* miss) { 3514 Label* out_of_bounds, Label* miss) {
3512 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this), 3515 Label if_typed_array(this), if_fast_packed(this), if_fast_holey(this),
3513 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this), 3516 if_fast_double(this), if_fast_holey_double(this), if_nonfast(this),
3514 if_dictionary(this), unreachable(this); 3517 if_dictionary(this), unreachable(this);
(...skipping 18 matching lines...) Expand all
3533 // FAST_DOUBLE_ELEMENTS 3536 // FAST_DOUBLE_ELEMENTS
3534 &if_fast_double, 3537 &if_fast_double,
3535 // FAST_HOLEY_DOUBLE_ELEMENTS 3538 // FAST_HOLEY_DOUBLE_ELEMENTS
3536 &if_fast_holey_double}; 3539 &if_fast_holey_double};
3537 Switch(elements_kind, unimplemented_elements_kind, kinds, labels, 3540 Switch(elements_kind, unimplemented_elements_kind, kinds, labels,
3538 arraysize(kinds)); 3541 arraysize(kinds));
3539 3542
3540 Bind(&if_fast_packed); 3543 Bind(&if_fast_packed);
3541 { 3544 {
3542 Comment("fast packed elements"); 3545 Comment("fast packed elements");
3543 // TODO(jkummerow): The Load*Element helpers add movsxlq instructions 3546 Return(LoadFixedArrayElement(elements, key, 0, INTPTR_PARAMETERS));
3544 // on x64 which we don't need here, because |key| is an IntPtr already.
3545 // Do something about that.
3546 Return(LoadFixedArrayElement(elements, key));
3547 } 3547 }
3548 3548
3549 Bind(&if_fast_holey); 3549 Bind(&if_fast_holey);
3550 { 3550 {
3551 Comment("fast holey elements"); 3551 Comment("fast holey elements");
3552 Node* element = LoadFixedArrayElement(elements, key); 3552 Node* element = LoadFixedArrayElement(elements, key, 0, INTPTR_PARAMETERS);
3553 GotoIf(WordEqual(element, TheHoleConstant()), if_hole); 3553 GotoIf(WordEqual(element, TheHoleConstant()), if_hole);
3554 Return(element); 3554 Return(element);
3555 } 3555 }
3556 3556
3557 Bind(&if_fast_double); 3557 Bind(&if_fast_double);
3558 { 3558 {
3559 Comment("packed double elements"); 3559 Comment("packed double elements");
3560 var_double_value->Bind( 3560 var_double_value->Bind(LoadFixedDoubleArrayElement(
3561 LoadFixedDoubleArrayElement(elements, key, MachineType::Float64())); 3561 elements, key, MachineType::Float64(), 0, INTPTR_PARAMETERS));
3562 Goto(rebox_double); 3562 Goto(rebox_double);
3563 } 3563 }
3564 3564
3565 Bind(&if_fast_holey_double); 3565 Bind(&if_fast_holey_double);
3566 { 3566 {
3567 Comment("holey double elements"); 3567 Comment("holey double elements");
3568 if (kPointerSize == kDoubleSize) { 3568 if (kPointerSize == kDoubleSize) {
3569 Node* raw_element = 3569 Node* raw_element = LoadFixedDoubleArrayElement(
3570 LoadFixedDoubleArrayElement(elements, key, MachineType::Uint64()); 3570 elements, key, MachineType::Uint64(), 0, INTPTR_PARAMETERS);
3571 Node* the_hole = Int64Constant(kHoleNanInt64); 3571 Node* the_hole = Int64Constant(kHoleNanInt64);
3572 GotoIf(Word64Equal(raw_element, the_hole), if_hole); 3572 GotoIf(Word64Equal(raw_element, the_hole), if_hole);
3573 } else { 3573 } else {
3574 Node* element_upper = LoadFixedDoubleArrayElement( 3574 Node* element_upper = LoadFixedDoubleArrayElement(
3575 elements, key, MachineType::Uint32(), kIeeeDoubleExponentWordOffset); 3575 elements, key, MachineType::Uint32(), kIeeeDoubleExponentWordOffset,
3576 INTPTR_PARAMETERS);
3576 GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), 3577 GotoIf(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)),
3577 if_hole); 3578 if_hole);
3578 } 3579 }
3579 var_double_value->Bind( 3580 var_double_value->Bind(LoadFixedDoubleArrayElement(
3580 LoadFixedDoubleArrayElement(elements, key, MachineType::Float64())); 3581 elements, key, MachineType::Float64(), 0, INTPTR_PARAMETERS));
3581 Goto(rebox_double); 3582 Goto(rebox_double);
3582 } 3583 }
3583 3584
3584 Bind(&if_nonfast); 3585 Bind(&if_nonfast);
3585 { 3586 {
3586 STATIC_ASSERT(LAST_ELEMENTS_KIND == LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND); 3587 STATIC_ASSERT(LAST_ELEMENTS_KIND == LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
3587 GotoIf(IntPtrGreaterThanOrEqual( 3588 GotoIf(IntPtrGreaterThanOrEqual(
3588 elements_kind, 3589 elements_kind,
3589 IntPtrConstant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND)), 3590 IntPtrConstant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND)),
3590 &if_typed_array); 3591 &if_typed_array);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3927 Bind(&miss); 3928 Bind(&miss);
3928 { 3929 {
3929 Comment("KeyedLoadIC_miss"); 3930 Comment("KeyedLoadIC_miss");
3930 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, 3931 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver,
3931 p->name, p->slot, p->vector); 3932 p->name, p->slot, p->vector);
3932 } 3933 }
3933 } 3934 }
3934 3935
3935 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { 3936 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
3936 Variable var_index(this, MachineType::PointerRepresentation()); 3937 Variable var_index(this, MachineType::PointerRepresentation());
3937 Label if_index(this), if_key_is_not_number(this), if_index_name(this), 3938 Label if_index(this), if_unique_name(this), if_element_hole(this),
3938 if_unique_name(this), if_element_hole(this), if_oob(this), slow(this), 3939 if_oob(this), slow(this), stub_cache_miss(this),
3939 stub_cache_miss(this), if_property_dictionary(this); 3940 if_property_dictionary(this);
3940 3941
3941 Node* receiver = p->receiver; 3942 Node* receiver = p->receiver;
3942 GotoIf(WordIsSmi(receiver), &slow); 3943 GotoIf(WordIsSmi(receiver), &slow);
3943 Node* receiver_map = LoadMap(receiver); 3944 Node* receiver_map = LoadMap(receiver);
3944 Node* instance_type = LoadMapInstanceType(receiver_map); 3945 Node* instance_type = LoadMapInstanceType(receiver_map);
3945 // Receivers requiring non-standard element accesses (interceptors, access 3946 // Receivers requiring non-standard element accesses (interceptors, access
3946 // checks, strings and string wrappers, proxies) are handled in the runtime. 3947 // checks, strings and string wrappers, proxies) are handled in the runtime.
3947 GotoIf(Int32LessThanOrEqual(instance_type, 3948 GotoIf(Int32LessThanOrEqual(instance_type,
3948 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), 3949 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)),
3949 &slow); 3950 &slow);
3950 3951
3951 // Check what kind of key we have.
3952 Node* key = p->name; 3952 Node* key = p->name;
3953 var_index.Bind(TryToIntptr(key, &if_key_is_not_number)); 3953 TryToName(key, &if_index, &var_index, &if_unique_name, &slow);
3954 Goto(&if_index);
3955
3956 Node* hash = nullptr;
3957 // TODO(jkummerow): Unify this with CodeStubAssembler::TryToName().
3958 Bind(&if_key_is_not_number);
3959 {
3960 Node* key_map = LoadMap(key);
3961 Node* key_instance_type = LoadMapInstanceType(key_map);
3962 // Jump to the runtime if key is neither String nor Symbol.
3963 GotoIf(Int32GreaterThan(key_instance_type,
3964 Int32Constant(LAST_UNIQUE_NAME_TYPE)),
3965 &slow);
3966 // Symbols are always unique names.
3967 GotoIf(Word32Equal(key_instance_type, Int32Constant(LAST_UNIQUE_NAME_TYPE)),
3968 &if_unique_name);
3969 // |key| is a String. Check if it has a cached array index.
3970 hash = LoadNameHashField(key);
3971 Node* contains_index =
3972 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
3973 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_index_name);
3974 // Otherwise, jump to the runtime if the string is not internalized.
3975 STATIC_ASSERT(kNotInternalizedTag != 0);
3976 Node* not_internalized =
3977 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
3978 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), &slow);
3979 Goto(&if_unique_name);
3980 }
3981
3982 Bind(&if_index_name);
3983 {
3984 Comment("string key with cached array index");
3985 var_index.Bind(BitFieldDecode<String::ArrayIndexValueBits>(hash));
3986 Goto(&if_index);
3987 }
3988 3954
3989 Bind(&if_index); 3955 Bind(&if_index);
3990 { 3956 {
3991 Comment("integer index"); 3957 Comment("integer index");
3992 Node* index = var_index.value(); 3958 Node* index = var_index.value();
3993 Node* elements = LoadElements(receiver); 3959 Node* elements = LoadElements(receiver);
3994 Node* bitfield2 = LoadMapBitField2(receiver_map); 3960 Node* bitfield2 = LoadMapBitField2(receiver_map);
3995 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bitfield2); 3961 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bitfield2);
3996 Node* is_jsarray_condition = 3962 Node* is_jsarray_condition =
3997 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); 3963 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 Heap::kTheHoleValueRootIndex); 4176 Heap::kTheHoleValueRootIndex);
4211 4177
4212 // Store the WeakCell in the feedback vector. 4178 // Store the WeakCell in the feedback vector.
4213 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 4179 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
4214 CodeStubAssembler::SMI_PARAMETERS); 4180 CodeStubAssembler::SMI_PARAMETERS);
4215 return cell; 4181 return cell;
4216 } 4182 }
4217 4183
4218 } // namespace internal 4184 } // namespace internal
4219 } // namespace v8 4185 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698