| OLD | NEW |
| 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 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 return result.value(); | 1066 return result.value(); |
| 1067 } | 1067 } |
| 1068 | 1068 |
| 1069 Node* CodeStubAssembler::LoadNameHashField(Node* name) { | 1069 Node* CodeStubAssembler::LoadNameHashField(Node* name) { |
| 1070 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); | 1070 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); |
| 1071 } | 1071 } |
| 1072 | 1072 |
| 1073 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { | 1073 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { |
| 1074 Node* hash_field = LoadNameHashField(name); | 1074 Node* hash_field = LoadNameHashField(name); |
| 1075 if (if_hash_not_computed != nullptr) { | 1075 if (if_hash_not_computed != nullptr) { |
| 1076 GotoIf(WordEqual( | 1076 GotoIf(Word32Equal( |
| 1077 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 1077 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
| 1078 Int32Constant(0)), | 1078 Int32Constant(0)), |
| 1079 if_hash_not_computed); | 1079 if_hash_not_computed); |
| 1080 } | 1080 } |
| 1081 return Word32Shr(hash_field, Int32Constant(Name::kHashShift)); | 1081 return Word32Shr(hash_field, Int32Constant(Name::kHashShift)); |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 Node* CodeStubAssembler::LoadStringLength(Node* object) { | 1084 Node* CodeStubAssembler::LoadStringLength(Node* object) { |
| 1085 return LoadObjectField(object, String::kLengthOffset); | 1085 return LoadObjectField(object, String::kLengthOffset); |
| 1086 } | 1086 } |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); | 2291 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); |
| 2292 Goto(if_keyisunique); | 2292 Goto(if_keyisunique); |
| 2293 | 2293 |
| 2294 Bind(&if_hascachedindex); | 2294 Bind(&if_hascachedindex); |
| 2295 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); | 2295 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); |
| 2296 Goto(if_keyisindex); | 2296 Goto(if_keyisindex); |
| 2297 } | 2297 } |
| 2298 | 2298 |
| 2299 template <typename Dictionary> | 2299 template <typename Dictionary> |
| 2300 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { | 2300 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |
| 2301 Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize)); | 2301 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); |
| 2302 return Int32Add(entry_index, | 2302 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + |
| 2303 Int32Constant(Dictionary::kElementsStartIndex + field_index)); | 2303 field_index)); |
| 2304 } | 2304 } |
| 2305 | 2305 |
| 2306 template <typename Dictionary> | 2306 template <typename Dictionary> |
| 2307 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, | 2307 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, |
| 2308 Node* unique_name, Label* if_found, | 2308 Node* unique_name, Label* if_found, |
| 2309 Variable* var_name_index, | 2309 Variable* var_name_index, |
| 2310 Label* if_not_found, | 2310 Label* if_not_found, |
| 2311 int inlined_probes) { | 2311 int inlined_probes) { |
| 2312 DCHECK_EQ(MachineRepresentation::kWord32, var_name_index->rep()); | 2312 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
| 2313 Comment("NameDictionaryLookup"); | 2313 Comment("NameDictionaryLookup"); |
| 2314 | 2314 |
| 2315 Node* capacity = LoadAndUntagToWord32FixedArrayElement( | 2315 Node* capacity = SmiUntag(LoadFixedArrayElement( |
| 2316 dictionary, Int32Constant(Dictionary::kCapacityIndex)); | 2316 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, |
| 2317 Node* mask = Int32Sub(capacity, Int32Constant(1)); | 2317 INTPTR_PARAMETERS)); |
| 2318 Node* hash = LoadNameHash(unique_name); | 2318 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); |
| 2319 Node* hash = ChangeUint32ToWord(LoadNameHash(unique_name)); |
| 2319 | 2320 |
| 2320 // See Dictionary::FirstProbe(). | 2321 // See Dictionary::FirstProbe(). |
| 2321 Node* count = Int32Constant(0); | 2322 Node* count = IntPtrConstant(0); |
| 2322 Node* entry = Word32And(hash, mask); | 2323 Node* entry = WordAnd(hash, mask); |
| 2323 | 2324 |
| 2324 for (int i = 0; i < inlined_probes; i++) { | 2325 for (int i = 0; i < inlined_probes; i++) { |
| 2325 Node* index = EntryToIndex<Dictionary>(entry); | 2326 Node* index = EntryToIndex<Dictionary>(entry); |
| 2326 var_name_index->Bind(index); | 2327 var_name_index->Bind(index); |
| 2327 | 2328 |
| 2328 Node* current = LoadFixedArrayElement(dictionary, index); | 2329 Node* current = |
| 2330 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
| 2329 GotoIf(WordEqual(current, unique_name), if_found); | 2331 GotoIf(WordEqual(current, unique_name), if_found); |
| 2330 | 2332 |
| 2331 // See Dictionary::NextProbe(). | 2333 // See Dictionary::NextProbe(). |
| 2332 count = Int32Constant(i + 1); | 2334 count = IntPtrConstant(i + 1); |
| 2333 entry = Word32And(Int32Add(entry, count), mask); | 2335 entry = WordAnd(IntPtrAdd(entry, count), mask); |
| 2334 } | 2336 } |
| 2335 | 2337 |
| 2336 Node* undefined = UndefinedConstant(); | 2338 Node* undefined = UndefinedConstant(); |
| 2337 | 2339 |
| 2338 Variable var_count(this, MachineRepresentation::kWord32); | 2340 Variable var_count(this, MachineType::PointerRepresentation()); |
| 2339 Variable var_entry(this, MachineRepresentation::kWord32); | 2341 Variable var_entry(this, MachineType::PointerRepresentation()); |
| 2340 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; | 2342 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; |
| 2341 Label loop(this, 3, loop_vars); | 2343 Label loop(this, 3, loop_vars); |
| 2342 var_count.Bind(count); | 2344 var_count.Bind(count); |
| 2343 var_entry.Bind(entry); | 2345 var_entry.Bind(entry); |
| 2344 Goto(&loop); | 2346 Goto(&loop); |
| 2345 Bind(&loop); | 2347 Bind(&loop); |
| 2346 { | 2348 { |
| 2347 Node* count = var_count.value(); | 2349 Node* count = var_count.value(); |
| 2348 Node* entry = var_entry.value(); | 2350 Node* entry = var_entry.value(); |
| 2349 | 2351 |
| 2350 Node* index = EntryToIndex<Dictionary>(entry); | 2352 Node* index = EntryToIndex<Dictionary>(entry); |
| 2351 var_name_index->Bind(index); | 2353 var_name_index->Bind(index); |
| 2352 | 2354 |
| 2353 Node* current = LoadFixedArrayElement(dictionary, index); | 2355 Node* current = |
| 2356 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
| 2354 GotoIf(WordEqual(current, undefined), if_not_found); | 2357 GotoIf(WordEqual(current, undefined), if_not_found); |
| 2355 GotoIf(WordEqual(current, unique_name), if_found); | 2358 GotoIf(WordEqual(current, unique_name), if_found); |
| 2356 | 2359 |
| 2357 // See Dictionary::NextProbe(). | 2360 // See Dictionary::NextProbe(). |
| 2358 count = Int32Add(count, Int32Constant(1)); | 2361 count = IntPtrAdd(count, IntPtrConstant(1)); |
| 2359 entry = Word32And(Int32Add(entry, count), mask); | 2362 entry = WordAnd(IntPtrAdd(entry, count), mask); |
| 2360 | 2363 |
| 2361 var_count.Bind(count); | 2364 var_count.Bind(count); |
| 2362 var_entry.Bind(entry); | 2365 var_entry.Bind(entry); |
| 2363 Goto(&loop); | 2366 Goto(&loop); |
| 2364 } | 2367 } |
| 2365 } | 2368 } |
| 2366 | 2369 |
| 2367 // Instantiate template methods to workaround GCC compilation issue. | 2370 // Instantiate template methods to workaround GCC compilation issue. |
| 2368 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( | 2371 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( |
| 2369 Node*, Node*, Label*, Variable*, Label*, int); | 2372 Node*, Node*, Label*, Variable*, Label*, int); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2383 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); | 2386 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); |
| 2384 return Word32And(hash, Int32Constant(0x3fffffff)); | 2387 return Word32And(hash, Int32Constant(0x3fffffff)); |
| 2385 } | 2388 } |
| 2386 | 2389 |
| 2387 template <typename Dictionary> | 2390 template <typename Dictionary> |
| 2388 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, | 2391 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, |
| 2389 Node* intptr_index, | 2392 Node* intptr_index, |
| 2390 Label* if_found, | 2393 Label* if_found, |
| 2391 Variable* var_entry, | 2394 Variable* var_entry, |
| 2392 Label* if_not_found) { | 2395 Label* if_not_found) { |
| 2393 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep()); | 2396 DCHECK_EQ(MachineType::PointerRepresentation(), var_entry->rep()); |
| 2394 Comment("NumberDictionaryLookup"); | 2397 Comment("NumberDictionaryLookup"); |
| 2395 | 2398 |
| 2396 Node* capacity = LoadAndUntagToWord32FixedArrayElement( | 2399 Node* capacity = SmiUntag(LoadFixedArrayElement( |
| 2397 dictionary, Int32Constant(Dictionary::kCapacityIndex)); | 2400 dictionary, IntPtrConstant(Dictionary::kCapacityIndex), 0, |
| 2398 Node* mask = Int32Sub(capacity, Int32Constant(1)); | 2401 INTPTR_PARAMETERS)); |
| 2402 Node* mask = IntPtrSub(capacity, IntPtrConstant(1)); |
| 2399 | 2403 |
| 2400 Node* seed; | 2404 Node* int32_seed; |
| 2401 if (Dictionary::ShapeT::UsesSeed) { | 2405 if (Dictionary::ShapeT::UsesSeed) { |
| 2402 seed = HashSeed(); | 2406 int32_seed = HashSeed(); |
| 2403 } else { | 2407 } else { |
| 2404 seed = Int32Constant(kZeroHashSeed); | 2408 int32_seed = Int32Constant(kZeroHashSeed); |
| 2405 } | 2409 } |
| 2406 Node* hash = ComputeIntegerHash(intptr_index, seed); | 2410 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); |
| 2407 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); | 2411 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); |
| 2408 | 2412 |
| 2409 // See Dictionary::FirstProbe(). | 2413 // See Dictionary::FirstProbe(). |
| 2410 Node* count = Int32Constant(0); | 2414 Node* count = IntPtrConstant(0); |
| 2411 Node* entry = Word32And(hash, mask); | 2415 Node* entry = WordAnd(hash, mask); |
| 2412 | 2416 |
| 2413 Node* undefined = UndefinedConstant(); | 2417 Node* undefined = UndefinedConstant(); |
| 2414 Node* the_hole = TheHoleConstant(); | 2418 Node* the_hole = TheHoleConstant(); |
| 2415 | 2419 |
| 2416 Variable var_count(this, MachineRepresentation::kWord32); | 2420 Variable var_count(this, MachineType::PointerRepresentation()); |
| 2417 Variable* loop_vars[] = {&var_count, var_entry}; | 2421 Variable* loop_vars[] = {&var_count, var_entry}; |
| 2418 Label loop(this, 2, loop_vars); | 2422 Label loop(this, 2, loop_vars); |
| 2419 var_count.Bind(count); | 2423 var_count.Bind(count); |
| 2420 var_entry->Bind(entry); | 2424 var_entry->Bind(entry); |
| 2421 Goto(&loop); | 2425 Goto(&loop); |
| 2422 Bind(&loop); | 2426 Bind(&loop); |
| 2423 { | 2427 { |
| 2424 Node* count = var_count.value(); | 2428 Node* count = var_count.value(); |
| 2425 Node* entry = var_entry->value(); | 2429 Node* entry = var_entry->value(); |
| 2426 | 2430 |
| 2427 Node* index = EntryToIndex<Dictionary>(entry); | 2431 Node* index = EntryToIndex<Dictionary>(entry); |
| 2428 Node* current = LoadFixedArrayElement(dictionary, index); | 2432 Node* current = |
| 2433 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
| 2429 GotoIf(WordEqual(current, undefined), if_not_found); | 2434 GotoIf(WordEqual(current, undefined), if_not_found); |
| 2430 Label next_probe(this); | 2435 Label next_probe(this); |
| 2431 { | 2436 { |
| 2432 Label if_currentissmi(this), if_currentisnotsmi(this); | 2437 Label if_currentissmi(this), if_currentisnotsmi(this); |
| 2433 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); | 2438 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); |
| 2434 Bind(&if_currentissmi); | 2439 Bind(&if_currentissmi); |
| 2435 { | 2440 { |
| 2436 Node* current_value = SmiUntag(current); | 2441 Node* current_value = SmiUntag(current); |
| 2437 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); | 2442 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); |
| 2438 } | 2443 } |
| 2439 Bind(&if_currentisnotsmi); | 2444 Bind(&if_currentisnotsmi); |
| 2440 { | 2445 { |
| 2441 GotoIf(WordEqual(current, the_hole), &next_probe); | 2446 GotoIf(WordEqual(current, the_hole), &next_probe); |
| 2442 // Current must be the Number. | 2447 // Current must be the Number. |
| 2443 Node* current_value = LoadHeapNumberValue(current); | 2448 Node* current_value = LoadHeapNumberValue(current); |
| 2444 Branch(Float64Equal(current_value, key_as_float64), if_found, | 2449 Branch(Float64Equal(current_value, key_as_float64), if_found, |
| 2445 &next_probe); | 2450 &next_probe); |
| 2446 } | 2451 } |
| 2447 } | 2452 } |
| 2448 | 2453 |
| 2449 Bind(&next_probe); | 2454 Bind(&next_probe); |
| 2450 // See Dictionary::NextProbe(). | 2455 // See Dictionary::NextProbe(). |
| 2451 count = Int32Add(count, Int32Constant(1)); | 2456 count = IntPtrAdd(count, IntPtrConstant(1)); |
| 2452 entry = Word32And(Int32Add(entry, count), mask); | 2457 entry = WordAnd(IntPtrAdd(entry, count), mask); |
| 2453 | 2458 |
| 2454 var_count.Bind(count); | 2459 var_count.Bind(count); |
| 2455 var_entry->Bind(entry); | 2460 var_entry->Bind(entry); |
| 2456 Goto(&loop); | 2461 Goto(&loop); |
| 2457 } | 2462 } |
| 2458 } | 2463 } |
| 2459 | 2464 |
| 2460 void CodeStubAssembler::TryLookupProperty( | 2465 void CodeStubAssembler::TryLookupProperty( |
| 2461 Node* object, Node* map, Node* instance_type, Node* unique_name, | 2466 Node* object, Node* map, Node* instance_type, Node* unique_name, |
| 2462 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, | 2467 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, |
| 2463 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, | 2468 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, |
| 2464 Label* if_bailout) { | 2469 Label* if_bailout) { |
| 2465 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); | 2470 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); |
| 2466 DCHECK_EQ(MachineRepresentation::kWord32, var_name_index->rep()); | 2471 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
| 2467 | 2472 |
| 2468 Label if_objectisspecial(this); | 2473 Label if_objectisspecial(this); |
| 2469 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 2474 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
| 2470 GotoIf(Int32LessThanOrEqual(instance_type, | 2475 GotoIf(Int32LessThanOrEqual(instance_type, |
| 2471 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | 2476 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
| 2472 &if_objectisspecial); | 2477 &if_objectisspecial); |
| 2473 | 2478 |
| 2474 Node* bit_field = LoadMapBitField(map); | 2479 Node* bit_field = LoadMapBitField(map); |
| 2475 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | | 2480 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | |
| 2476 1 << Map::kIsAccessCheckNeeded); | 2481 1 << Map::kIsAccessCheckNeeded); |
| 2477 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 2482 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); |
| 2478 | 2483 |
| 2479 Node* bit_field3 = LoadMapBitField3(map); | 2484 Node* bit_field3 = LoadMapBitField3(map); |
| 2480 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3); | 2485 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3); |
| 2481 Label if_isfastmap(this), if_isslowmap(this); | 2486 Label if_isfastmap(this), if_isslowmap(this); |
| 2482 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); | 2487 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); |
| 2483 Bind(&if_isfastmap); | 2488 Bind(&if_isfastmap); |
| 2484 { | 2489 { |
| 2485 Comment("DescriptorArrayLookup"); | 2490 Comment("DescriptorArrayLookup"); |
| 2486 Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3); | 2491 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3); |
| 2487 // Bail out to the runtime for large numbers of own descriptors. The stub | 2492 // Bail out to the runtime for large numbers of own descriptors. The stub |
| 2488 // only does linear search, which becomes too expensive in that case. | 2493 // only does linear search, which becomes too expensive in that case. |
| 2489 { | 2494 { |
| 2490 static const int32_t kMaxLinear = 210; | 2495 static const int32_t kMaxLinear = 210; |
| 2491 GotoIf(Int32GreaterThan(nof, Int32Constant(kMaxLinear)), if_bailout); | 2496 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout); |
| 2492 } | 2497 } |
| 2493 Node* descriptors = LoadMapDescriptors(map); | 2498 Node* descriptors = LoadMapDescriptors(map); |
| 2494 var_meta_storage->Bind(descriptors); | 2499 var_meta_storage->Bind(descriptors); |
| 2495 | 2500 |
| 2496 Variable var_descriptor(this, MachineRepresentation::kWord32); | 2501 Variable var_descriptor(this, MachineType::PointerRepresentation()); |
| 2497 Label loop(this, &var_descriptor); | 2502 Label loop(this, &var_descriptor); |
| 2498 var_descriptor.Bind(Int32Constant(0)); | 2503 var_descriptor.Bind(IntPtrConstant(0)); |
| 2499 Goto(&loop); | 2504 Goto(&loop); |
| 2500 Bind(&loop); | 2505 Bind(&loop); |
| 2501 { | 2506 { |
| 2502 Node* index = var_descriptor.value(); | 2507 Node* index = var_descriptor.value(); |
| 2503 Node* name_offset = Int32Constant(DescriptorArray::ToKeyIndex(0)); | 2508 Node* name_offset = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); |
| 2504 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize); | 2509 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); |
| 2505 GotoIf(Word32Equal(index, nof), if_not_found); | 2510 GotoIf(WordEqual(index, nof), if_not_found); |
| 2506 | 2511 |
| 2507 Node* name_index = Int32Add(name_offset, Int32Mul(index, factor)); | 2512 Node* name_index = IntPtrAdd(name_offset, IntPtrMul(index, factor)); |
| 2508 Node* name = LoadFixedArrayElement(descriptors, name_index); | 2513 Node* name = |
| 2514 LoadFixedArrayElement(descriptors, name_index, 0, INTPTR_PARAMETERS); |
| 2509 | 2515 |
| 2510 var_name_index->Bind(name_index); | 2516 var_name_index->Bind(name_index); |
| 2511 GotoIf(WordEqual(name, unique_name), if_found_fast); | 2517 GotoIf(WordEqual(name, unique_name), if_found_fast); |
| 2512 | 2518 |
| 2513 var_descriptor.Bind(Int32Add(index, Int32Constant(1))); | 2519 var_descriptor.Bind(IntPtrAdd(index, IntPtrConstant(1))); |
| 2514 Goto(&loop); | 2520 Goto(&loop); |
| 2515 } | 2521 } |
| 2516 } | 2522 } |
| 2517 Bind(&if_isslowmap); | 2523 Bind(&if_isslowmap); |
| 2518 { | 2524 { |
| 2519 Node* dictionary = LoadProperties(object); | 2525 Node* dictionary = LoadProperties(object); |
| 2520 var_meta_storage->Bind(dictionary); | 2526 var_meta_storage->Bind(dictionary); |
| 2521 | 2527 |
| 2522 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, | 2528 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, |
| 2523 var_name_index, if_not_found); | 2529 var_name_index, if_not_found); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2544 } | 2550 } |
| 2545 | 2551 |
| 2546 void CodeStubAssembler::TryHasOwnProperty(compiler::Node* object, | 2552 void CodeStubAssembler::TryHasOwnProperty(compiler::Node* object, |
| 2547 compiler::Node* map, | 2553 compiler::Node* map, |
| 2548 compiler::Node* instance_type, | 2554 compiler::Node* instance_type, |
| 2549 compiler::Node* unique_name, | 2555 compiler::Node* unique_name, |
| 2550 Label* if_found, Label* if_not_found, | 2556 Label* if_found, Label* if_not_found, |
| 2551 Label* if_bailout) { | 2557 Label* if_bailout) { |
| 2552 Comment("TryHasOwnProperty"); | 2558 Comment("TryHasOwnProperty"); |
| 2553 Variable var_meta_storage(this, MachineRepresentation::kTagged); | 2559 Variable var_meta_storage(this, MachineRepresentation::kTagged); |
| 2554 Variable var_name_index(this, MachineRepresentation::kWord32); | 2560 Variable var_name_index(this, MachineType::PointerRepresentation()); |
| 2555 | 2561 |
| 2556 Label if_found_global(this); | 2562 Label if_found_global(this); |
| 2557 TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found, | 2563 TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found, |
| 2558 &if_found_global, &var_meta_storage, &var_name_index, | 2564 &if_found_global, &var_meta_storage, &var_name_index, |
| 2559 if_not_found, if_bailout); | 2565 if_not_found, if_bailout); |
| 2560 Bind(&if_found_global); | 2566 Bind(&if_found_global); |
| 2561 { | 2567 { |
| 2562 Variable var_value(this, MachineRepresentation::kTagged); | 2568 Variable var_value(this, MachineRepresentation::kTagged); |
| 2563 Variable var_details(this, MachineRepresentation::kWord32); | 2569 Variable var_details(this, MachineRepresentation::kWord32); |
| 2564 // Check if the property cell is not deleted. | 2570 // Check if the property cell is not deleted. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2729 } | 2735 } |
| 2730 | 2736 |
| 2731 void CodeStubAssembler::TryGetOwnProperty( | 2737 void CodeStubAssembler::TryGetOwnProperty( |
| 2732 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type, | 2738 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type, |
| 2733 Node* unique_name, Label* if_found_value, Variable* var_value, | 2739 Node* unique_name, Label* if_found_value, Variable* var_value, |
| 2734 Label* if_not_found, Label* if_bailout) { | 2740 Label* if_not_found, Label* if_bailout) { |
| 2735 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); | 2741 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); |
| 2736 Comment("TryGetOwnProperty"); | 2742 Comment("TryGetOwnProperty"); |
| 2737 | 2743 |
| 2738 Variable var_meta_storage(this, MachineRepresentation::kTagged); | 2744 Variable var_meta_storage(this, MachineRepresentation::kTagged); |
| 2739 Variable var_entry(this, MachineRepresentation::kWord32); | 2745 Variable var_entry(this, MachineType::PointerRepresentation()); |
| 2740 | 2746 |
| 2741 Label if_found_fast(this), if_found_dict(this), if_found_global(this); | 2747 Label if_found_fast(this), if_found_dict(this), if_found_global(this); |
| 2742 | 2748 |
| 2743 Variable var_details(this, MachineRepresentation::kWord32); | 2749 Variable var_details(this, MachineRepresentation::kWord32); |
| 2744 Variable* vars[] = {var_value, &var_details}; | 2750 Variable* vars[] = {var_value, &var_details}; |
| 2745 Label if_found(this, 2, vars); | 2751 Label if_found(this, 2, vars); |
| 2746 | 2752 |
| 2747 TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast, | 2753 TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast, |
| 2748 &if_found_dict, &if_found_global, &var_meta_storage, | 2754 &if_found_dict, &if_found_global, &var_meta_storage, |
| 2749 &var_entry, if_not_found, if_bailout); | 2755 &var_entry, if_not_found, if_bailout); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2885 } else { | 2891 } else { |
| 2886 Node* element_upper = LoadFixedDoubleArrayElement( | 2892 Node* element_upper = LoadFixedDoubleArrayElement( |
| 2887 elements, intptr_index, MachineType::Uint32(), | 2893 elements, intptr_index, MachineType::Uint32(), |
| 2888 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); | 2894 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); |
| 2889 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), | 2895 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), |
| 2890 if_not_found, if_found); | 2896 if_not_found, if_found); |
| 2891 } | 2897 } |
| 2892 } | 2898 } |
| 2893 Bind(&if_isdictionary); | 2899 Bind(&if_isdictionary); |
| 2894 { | 2900 { |
| 2895 Variable var_entry(this, MachineRepresentation::kWord32); | 2901 Variable var_entry(this, MachineType::PointerRepresentation()); |
| 2896 Node* elements = LoadElements(object); | 2902 Node* elements = LoadElements(object); |
| 2897 NumberDictionaryLookup<SeededNumberDictionary>( | 2903 NumberDictionaryLookup<SeededNumberDictionary>( |
| 2898 elements, intptr_index, if_found, &var_entry, if_not_found); | 2904 elements, intptr_index, if_found, &var_entry, if_not_found); |
| 2899 } | 2905 } |
| 2900 Bind(&if_isfaststringwrapper); | 2906 Bind(&if_isfaststringwrapper); |
| 2901 { | 2907 { |
| 2902 AssertInstanceType(object, JS_VALUE_TYPE); | 2908 AssertInstanceType(object, JS_VALUE_TYPE); |
| 2903 Node* string = LoadJSValueValue(object); | 2909 Node* string = LoadJSValueValue(object); |
| 2904 Assert(Int32LessThan(LoadInstanceType(string), | 2910 Assert(Int32LessThan(LoadInstanceType(string), |
| 2905 Int32Constant(FIRST_NONSTRING_TYPE))); | 2911 Int32Constant(FIRST_NONSTRING_TYPE))); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3305 const LoadICParameters* p, compiler::Node* receiver_map, | 3311 const LoadICParameters* p, compiler::Node* receiver_map, |
| 3306 compiler::Node* feedback, Label* if_handler, Variable* var_handler, | 3312 compiler::Node* feedback, Label* if_handler, Variable* var_handler, |
| 3307 Label* if_miss, int unroll_count) { | 3313 Label* if_miss, int unroll_count) { |
| 3308 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); | 3314 DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); |
| 3309 | 3315 |
| 3310 // Iterate {feedback} array. | 3316 // Iterate {feedback} array. |
| 3311 const int kEntrySize = 2; | 3317 const int kEntrySize = 2; |
| 3312 | 3318 |
| 3313 for (int i = 0; i < unroll_count; i++) { | 3319 for (int i = 0; i < unroll_count; i++) { |
| 3314 Label next_entry(this); | 3320 Label next_entry(this); |
| 3315 Node* cached_map = LoadWeakCellValue( | 3321 Node* cached_map = LoadWeakCellValue(LoadFixedArrayElement( |
| 3316 LoadFixedArrayElement(feedback, Int32Constant(i * kEntrySize))); | 3322 feedback, IntPtrConstant(i * kEntrySize), 0, INTPTR_PARAMETERS)); |
| 3317 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 3323 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
| 3318 | 3324 |
| 3319 // Found, now call handler. | 3325 // Found, now call handler. |
| 3320 Node* handler = | 3326 Node* handler = LoadFixedArrayElement( |
| 3321 LoadFixedArrayElement(feedback, Int32Constant(i * kEntrySize + 1)); | 3327 feedback, IntPtrConstant(i * kEntrySize + 1), 0, INTPTR_PARAMETERS); |
| 3322 var_handler->Bind(handler); | 3328 var_handler->Bind(handler); |
| 3323 Goto(if_handler); | 3329 Goto(if_handler); |
| 3324 | 3330 |
| 3325 Bind(&next_entry); | 3331 Bind(&next_entry); |
| 3326 } | 3332 } |
| 3327 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); | 3333 Node* length = LoadAndUntagFixedArrayBaseLength(feedback); |
| 3328 | 3334 |
| 3329 // Loop from {unroll_count}*kEntrySize to {length}. | 3335 // Loop from {unroll_count}*kEntrySize to {length}. |
| 3330 Variable var_index(this, MachineRepresentation::kWord32); | 3336 Variable var_index(this, MachineType::PointerRepresentation()); |
| 3331 Label loop(this, &var_index); | 3337 Label loop(this, &var_index); |
| 3332 var_index.Bind(Int32Constant(unroll_count * kEntrySize)); | 3338 var_index.Bind(IntPtrConstant(unroll_count * kEntrySize)); |
| 3333 Goto(&loop); | 3339 Goto(&loop); |
| 3334 Bind(&loop); | 3340 Bind(&loop); |
| 3335 { | 3341 { |
| 3336 Node* index = var_index.value(); | 3342 Node* index = var_index.value(); |
| 3337 GotoIf(Int32GreaterThanOrEqual(index, length), if_miss); | 3343 GotoIf(UintPtrGreaterThanOrEqual(index, length), if_miss); |
| 3338 | 3344 |
| 3339 Node* cached_map = | 3345 Node* cached_map = LoadWeakCellValue( |
| 3340 LoadWeakCellValue(LoadFixedArrayElement(feedback, index)); | 3346 LoadFixedArrayElement(feedback, index, 0, INTPTR_PARAMETERS)); |
| 3341 | 3347 |
| 3342 Label next_entry(this); | 3348 Label next_entry(this); |
| 3343 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); | 3349 GotoIf(WordNotEqual(receiver_map, cached_map), &next_entry); |
| 3344 | 3350 |
| 3345 // Found, now call handler. | 3351 // Found, now call handler. |
| 3346 Node* handler = LoadFixedArrayElement(feedback, index, kPointerSize); | 3352 Node* handler = |
| 3353 LoadFixedArrayElement(feedback, index, kPointerSize, INTPTR_PARAMETERS); |
| 3347 var_handler->Bind(handler); | 3354 var_handler->Bind(handler); |
| 3348 Goto(if_handler); | 3355 Goto(if_handler); |
| 3349 | 3356 |
| 3350 Bind(&next_entry); | 3357 Bind(&next_entry); |
| 3351 var_index.Bind(Int32Add(index, Int32Constant(kEntrySize))); | 3358 var_index.Bind(IntPtrAdd(index, IntPtrConstant(kEntrySize))); |
| 3352 Goto(&loop); | 3359 Goto(&loop); |
| 3353 } | 3360 } |
| 3354 } | 3361 } |
| 3355 | 3362 |
| 3356 compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name, | 3363 compiler::Node* CodeStubAssembler::StubCachePrimaryOffset(compiler::Node* name, |
| 3357 compiler::Node* map) { | 3364 compiler::Node* map) { |
| 3358 // See v8::internal::StubCache::PrimaryOffset(). | 3365 // See v8::internal::StubCache::PrimaryOffset(). |
| 3359 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); | 3366 STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); |
| 3360 // Compute the hash of the name (use entire hash field). | 3367 // Compute the hash of the name (use entire hash field). |
| 3361 Node* hash_field = LoadNameHashField(name); | 3368 Node* hash_field = LoadNameHashField(name); |
| 3362 Assert(WordEqual( | 3369 Assert(Word32Equal( |
| 3363 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), | 3370 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), |
| 3364 Int32Constant(0))); | 3371 Int32Constant(0))); |
| 3365 | 3372 |
| 3366 // Using only the low bits in 64-bit mode is unlikely to increase the | 3373 // Using only the low bits in 64-bit mode is unlikely to increase the |
| 3367 // risk of collision even if the heap is spread over an area larger than | 3374 // risk of collision even if the heap is spread over an area larger than |
| 3368 // 4Gb (and not at all if it isn't). | 3375 // 4Gb (and not at all if it isn't). |
| 3369 Node* hash = Int32Add(hash_field, map); | 3376 Node* hash = Int32Add(hash_field, map); |
| 3370 // Base the offset on a simple combination of name and map. | 3377 // Base the offset on a simple combination of name and map. |
| 3371 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); | 3378 hash = Word32Xor(hash, Int32Constant(StubCache::kPrimaryMagic)); |
| 3372 uint32_t mask = (StubCache::kPrimaryTableSize - 1) | 3379 uint32_t mask = (StubCache::kPrimaryTableSize - 1) |
| 3373 << StubCache::kCacheIndexShift; | 3380 << StubCache::kCacheIndexShift; |
| 3374 return Word32And(hash, Int32Constant(mask)); | 3381 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); |
| 3375 } | 3382 } |
| 3376 | 3383 |
| 3377 compiler::Node* CodeStubAssembler::StubCacheSecondaryOffset( | 3384 compiler::Node* CodeStubAssembler::StubCacheSecondaryOffset( |
| 3378 compiler::Node* name, compiler::Node* seed) { | 3385 compiler::Node* name, compiler::Node* seed) { |
| 3379 // See v8::internal::StubCache::SecondaryOffset(). | 3386 // See v8::internal::StubCache::SecondaryOffset(). |
| 3380 | 3387 |
| 3381 // Use the seed from the primary cache in the secondary cache. | 3388 // Use the seed from the primary cache in the secondary cache. |
| 3382 Node* hash = Int32Sub(seed, name); | 3389 Node* hash = Int32Sub(seed, name); |
| 3383 hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); | 3390 hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); |
| 3384 int32_t mask = (StubCache::kSecondaryTableSize - 1) | 3391 int32_t mask = (StubCache::kSecondaryTableSize - 1) |
| 3385 << StubCache::kCacheIndexShift; | 3392 << StubCache::kCacheIndexShift; |
| 3386 return Word32And(hash, Int32Constant(mask)); | 3393 return ChangeUint32ToWord(Word32And(hash, Int32Constant(mask))); |
| 3387 } | 3394 } |
| 3388 | 3395 |
| 3389 enum CodeStubAssembler::StubCacheTable : int { | 3396 enum CodeStubAssembler::StubCacheTable : int { |
| 3390 kPrimary = static_cast<int>(StubCache::kPrimary), | 3397 kPrimary = static_cast<int>(StubCache::kPrimary), |
| 3391 kSecondary = static_cast<int>(StubCache::kSecondary) | 3398 kSecondary = static_cast<int>(StubCache::kSecondary) |
| 3392 }; | 3399 }; |
| 3393 | 3400 |
| 3394 void CodeStubAssembler::TryProbeStubCacheTable( | 3401 void CodeStubAssembler::TryProbeStubCacheTable( |
| 3395 StubCache* stub_cache, StubCacheTable table_id, | 3402 StubCache* stub_cache, StubCacheTable table_id, |
| 3396 compiler::Node* entry_offset, compiler::Node* name, compiler::Node* map, | 3403 compiler::Node* entry_offset, compiler::Node* name, compiler::Node* map, |
| 3397 Label* if_handler, Variable* var_handler, Label* if_miss) { | 3404 Label* if_handler, Variable* var_handler, Label* if_miss) { |
| 3398 StubCache::Table table = static_cast<StubCache::Table>(table_id); | 3405 StubCache::Table table = static_cast<StubCache::Table>(table_id); |
| 3399 #ifdef DEBUG | 3406 #ifdef DEBUG |
| 3400 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { | 3407 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { |
| 3401 Goto(if_miss); | 3408 Goto(if_miss); |
| 3402 return; | 3409 return; |
| 3403 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { | 3410 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { |
| 3404 Goto(if_miss); | 3411 Goto(if_miss); |
| 3405 return; | 3412 return; |
| 3406 } | 3413 } |
| 3407 #endif | 3414 #endif |
| 3408 // The {table_offset} holds the entry offset times four (due to masking | 3415 // The {table_offset} holds the entry offset times four (due to masking |
| 3409 // and shifting optimizations). | 3416 // and shifting optimizations). |
| 3410 const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; | 3417 const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; |
| 3411 entry_offset = Int32Mul(entry_offset, Int32Constant(kMultiplier)); | 3418 entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier)); |
| 3412 | 3419 |
| 3413 // Check that the key in the entry matches the name. | 3420 // Check that the key in the entry matches the name. |
| 3414 Node* key_base = | 3421 Node* key_base = |
| 3415 ExternalConstant(ExternalReference(stub_cache->key_reference(table))); | 3422 ExternalConstant(ExternalReference(stub_cache->key_reference(table))); |
| 3416 Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset); | 3423 Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset); |
| 3417 GotoIf(WordNotEqual(name, entry_key), if_miss); | 3424 GotoIf(WordNotEqual(name, entry_key), if_miss); |
| 3418 | 3425 |
| 3419 // Get the map entry from the cache. | 3426 // Get the map entry from the cache. |
| 3420 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() - | 3427 DCHECK_EQ(kPointerSize * 2, stub_cache->map_reference(table).address() - |
| 3421 stub_cache->key_reference(table).address()); | 3428 stub_cache->key_reference(table).address()); |
| 3422 Node* entry_map = | 3429 Node* entry_map = |
| 3423 Load(MachineType::Pointer(), key_base, | 3430 Load(MachineType::Pointer(), key_base, |
| 3424 Int32Add(entry_offset, Int32Constant(kPointerSize * 2))); | 3431 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize * 2))); |
| 3425 GotoIf(WordNotEqual(map, entry_map), if_miss); | 3432 GotoIf(WordNotEqual(map, entry_map), if_miss); |
| 3426 | 3433 |
| 3427 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - | 3434 DCHECK_EQ(kPointerSize, stub_cache->value_reference(table).address() - |
| 3428 stub_cache->key_reference(table).address()); | 3435 stub_cache->key_reference(table).address()); |
| 3429 Node* code = Load(MachineType::Pointer(), key_base, | 3436 Node* code = Load(MachineType::Pointer(), key_base, |
| 3430 Int32Add(entry_offset, Int32Constant(kPointerSize))); | 3437 IntPtrAdd(entry_offset, IntPtrConstant(kPointerSize))); |
| 3431 | 3438 |
| 3432 // We found the handler. | 3439 // We found the handler. |
| 3433 var_handler->Bind(code); | 3440 var_handler->Bind(code); |
| 3434 Goto(if_handler); | 3441 Goto(if_handler); |
| 3435 } | 3442 } |
| 3436 | 3443 |
| 3437 void CodeStubAssembler::TryProbeStubCache( | 3444 void CodeStubAssembler::TryProbeStubCache( |
| 3438 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, | 3445 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, |
| 3439 Label* if_handler, Variable* var_handler, Label* if_miss) { | 3446 Label* if_handler, Variable* var_handler, Label* if_miss) { |
| 3440 Label try_secondary(this), miss(this); | 3447 Label try_secondary(this), miss(this); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3489 | 3496 |
| 3490 Bind(&done); | 3497 Bind(&done); |
| 3491 return var_intptr_key.value(); | 3498 return var_intptr_key.value(); |
| 3492 } | 3499 } |
| 3493 | 3500 |
| 3494 void CodeStubAssembler::EmitFastElementsBoundsCheck(Node* object, | 3501 void CodeStubAssembler::EmitFastElementsBoundsCheck(Node* object, |
| 3495 Node* elements, | 3502 Node* elements, |
| 3496 Node* intptr_index, | 3503 Node* intptr_index, |
| 3497 Node* is_jsarray_condition, | 3504 Node* is_jsarray_condition, |
| 3498 Label* miss) { | 3505 Label* miss) { |
| 3499 Variable var_length(this, MachineRepresentation::kTagged); | 3506 Variable var_length(this, MachineType::PointerRepresentation()); |
| 3500 Label if_array(this), length_loaded(this, &var_length); | 3507 Label if_array(this), length_loaded(this, &var_length); |
| 3501 GotoIf(is_jsarray_condition, &if_array); | 3508 GotoIf(is_jsarray_condition, &if_array); |
| 3502 { | 3509 { |
| 3503 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); | 3510 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); |
| 3504 Goto(&length_loaded); | 3511 Goto(&length_loaded); |
| 3505 } | 3512 } |
| 3506 Bind(&if_array); | 3513 Bind(&if_array); |
| 3507 { | 3514 { |
| 3508 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset))); | 3515 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset))); |
| 3509 Goto(&length_loaded); | 3516 Goto(&length_loaded); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3599 &if_typed_array); | 3606 &if_typed_array); |
| 3600 GotoIf(IntPtrEqual(elements_kind, IntPtrConstant(DICTIONARY_ELEMENTS)), | 3607 GotoIf(IntPtrEqual(elements_kind, IntPtrConstant(DICTIONARY_ELEMENTS)), |
| 3601 &if_dictionary); | 3608 &if_dictionary); |
| 3602 Goto(unimplemented_elements_kind); | 3609 Goto(unimplemented_elements_kind); |
| 3603 } | 3610 } |
| 3604 | 3611 |
| 3605 Bind(&if_dictionary); | 3612 Bind(&if_dictionary); |
| 3606 { | 3613 { |
| 3607 Comment("dictionary elements"); | 3614 Comment("dictionary elements"); |
| 3608 GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds); | 3615 GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), out_of_bounds); |
| 3609 Variable var_entry(this, MachineRepresentation::kWord32); | 3616 Variable var_entry(this, MachineType::PointerRepresentation()); |
| 3610 Label if_found(this); | 3617 Label if_found(this); |
| 3611 NumberDictionaryLookup<SeededNumberDictionary>( | 3618 NumberDictionaryLookup<SeededNumberDictionary>( |
| 3612 elements, intptr_index, &if_found, &var_entry, if_hole); | 3619 elements, intptr_index, &if_found, &var_entry, if_hole); |
| 3613 Bind(&if_found); | 3620 Bind(&if_found); |
| 3614 // Check that the value is a data property. | 3621 // Check that the value is a data property. |
| 3615 Node* details_index = EntryToIndex<SeededNumberDictionary>( | 3622 Node* details_index = EntryToIndex<SeededNumberDictionary>( |
| 3616 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex); | 3623 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex); |
| 3617 Node* details = SmiToWord32(LoadFixedArrayElement(elements, details_index)); | 3624 Node* details = SmiToWord32( |
| 3625 LoadFixedArrayElement(elements, details_index, 0, INTPTR_PARAMETERS)); |
| 3618 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); | 3626 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); |
| 3619 // TODO(jkummerow): Support accessors without missing? | 3627 // TODO(jkummerow): Support accessors without missing? |
| 3620 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss); | 3628 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss); |
| 3621 // Finally, load the value. | 3629 // Finally, load the value. |
| 3622 Node* value_index = EntryToIndex<SeededNumberDictionary>( | 3630 Node* value_index = EntryToIndex<SeededNumberDictionary>( |
| 3623 var_entry.value(), SeededNumberDictionary::kEntryValueIndex); | 3631 var_entry.value(), SeededNumberDictionary::kEntryValueIndex); |
| 3624 Return(LoadFixedArrayElement(elements, value_index)); | 3632 Return(LoadFixedArrayElement(elements, value_index, 0, INTPTR_PARAMETERS)); |
| 3625 } | 3633 } |
| 3626 | 3634 |
| 3627 Bind(&if_typed_array); | 3635 Bind(&if_typed_array); |
| 3628 { | 3636 { |
| 3629 Comment("typed elements"); | 3637 Comment("typed elements"); |
| 3630 // Check if buffer has been neutered. | 3638 // Check if buffer has been neutered. |
| 3631 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); | 3639 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); |
| 3632 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, | 3640 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, |
| 3633 MachineType::Uint32()); | 3641 MachineType::Uint32()); |
| 3634 Node* neutered_bit = | 3642 Node* neutered_bit = |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4030 p->name, p->slot, p->vector); | 4038 p->name, p->slot, p->vector); |
| 4031 } | 4039 } |
| 4032 } | 4040 } |
| 4033 | 4041 |
| 4034 Bind(&if_property_dictionary); | 4042 Bind(&if_property_dictionary); |
| 4035 { | 4043 { |
| 4036 Comment("dictionary property load"); | 4044 Comment("dictionary property load"); |
| 4037 // We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out | 4045 // We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out |
| 4038 // seeing global objects here (which would need special handling). | 4046 // seeing global objects here (which would need special handling). |
| 4039 | 4047 |
| 4040 Variable var_name_index(this, MachineRepresentation::kWord32); | 4048 Variable var_name_index(this, MachineType::PointerRepresentation()); |
| 4041 Label dictionary_found(this, &var_name_index); | 4049 Label dictionary_found(this, &var_name_index); |
| 4042 NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, | 4050 NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, |
| 4043 &var_name_index, &slow); | 4051 &var_name_index, &slow); |
| 4044 Bind(&dictionary_found); | 4052 Bind(&dictionary_found); |
| 4045 { | 4053 { |
| 4046 Variable var_details(this, MachineRepresentation::kWord32); | 4054 Variable var_details(this, MachineRepresentation::kWord32); |
| 4047 Variable var_value(this, MachineRepresentation::kTagged); | 4055 Variable var_value(this, MachineRepresentation::kTagged); |
| 4048 LoadPropertyFromNameDictionary(properties, var_name_index.value(), | 4056 LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
| 4049 &var_details, &var_value); | 4057 &var_details, &var_value); |
| 4050 Node* kind = | 4058 Node* kind = |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4185 Heap::kTheHoleValueRootIndex); | 4193 Heap::kTheHoleValueRootIndex); |
| 4186 | 4194 |
| 4187 // Store the WeakCell in the feedback vector. | 4195 // Store the WeakCell in the feedback vector. |
| 4188 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 4196 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
| 4189 CodeStubAssembler::SMI_PARAMETERS); | 4197 CodeStubAssembler::SMI_PARAMETERS); |
| 4190 return cell; | 4198 return cell; |
| 4191 } | 4199 } |
| 4192 | 4200 |
| 4193 } // namespace internal | 4201 } // namespace internal |
| 4194 } // namespace v8 | 4202 } // namespace v8 |
| OLD | NEW |