OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 12096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12107 | 12107 |
12108 void HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) { | 12108 void HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) { |
12109 DCHECK(call->arguments()->length() == 1); | 12109 DCHECK(call->arguments()->length() == 1); |
12110 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12110 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
12111 HValue* value = Pop(); | 12111 HValue* value = Pop(); |
12112 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt); | 12112 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt); |
12113 return ast_context()->ReturnInstruction(result, call->id()); | 12113 return ast_context()->ReturnInstruction(result, call->id()); |
12114 } | 12114 } |
12115 | 12115 |
12116 | 12116 |
12117 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToBucket( | |
12118 HValue* hash, HValue* num_buckets) { | |
12119 HValue* mask = AddUncasted<HSub>(num_buckets, graph()->GetConstant1()); | |
12120 mask->ChangeRepresentation(Representation::Integer32()); | |
12121 mask->ClearFlag(HValue::kCanOverflow); | |
12122 return AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); | |
12123 } | |
12124 | |
12125 | |
12126 template <typename CollectionType> | |
12127 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToEntry( | |
12128 HValue* table, HValue* hash, HValue* num_buckets) { | |
12129 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets); | |
12130 HValue* entry_index = AddUncasted<HAdd>( | |
12131 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex)); | |
12132 entry_index->ClearFlag(HValue::kCanOverflow); | |
12133 HValue* entry = Add<HLoadKeyed>(table, entry_index, | |
12134 static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
12135 entry->set_type(HType::Smi()); | |
12136 return entry; | |
12137 } | |
12138 | |
12139 | |
12140 template <typename CollectionType> | |
12141 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableEntryToIndex( | |
12142 HValue* entry, HValue* num_buckets) { | |
12143 HValue* index = | |
12144 AddUncasted<HMul>(entry, Add<HConstant>(CollectionType::kEntrySize)); | |
12145 index->ClearFlag(HValue::kCanOverflow); | |
12146 index = AddUncasted<HAdd>(index, num_buckets); | |
12147 index->ClearFlag(HValue::kCanOverflow); | |
12148 index = AddUncasted<HAdd>( | |
12149 index, Add<HConstant>(CollectionType::kHashTableStartIndex)); | |
12150 index->ClearFlag(HValue::kCanOverflow); | |
12151 return index; | |
12152 } | |
12153 | |
12154 | |
12155 template <typename CollectionType> | 12117 template <typename CollectionType> |
12156 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table, | 12118 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table, |
12157 HValue* key, | 12119 HValue* key, |
12158 HValue* hash) { | 12120 HValue* hash) { |
12159 HValue* num_buckets = Add<HLoadNamedField>( | 12121 HValue* num_buckets = Add<HLoadNamedField>( |
12160 table, static_cast<HValue*>(NULL), | 12122 table, static_cast<HValue*>(NULL), |
12161 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); | 12123 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); |
12162 | 12124 |
12163 HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash, | 12125 // Some things that won't change inside the loop |
12164 num_buckets); | 12126 HValue* not_found = Add<HConstant>(CollectionType::kNotFound); |
| 12127 HValue* start_index = Add<HConstant>(CollectionType::kHashTableStartIndex); |
| 12128 HValue* entry_size = Add<HConstant>(CollectionType::kEntrySize); |
| 12129 HValue* chain_offset = Add<HConstant>(CollectionType::kChainOffset); |
| 12130 HValue* key_start = AddUncasted<HAdd>(start_index, num_buckets); |
| 12131 key_start->ClearFlag(HValue::kCanOverflow); |
| 12132 |
| 12133 // BuildHashToBucket |
| 12134 HValue* mask = AddUncasted<HSub>(num_buckets, graph()->GetConstant1()); |
| 12135 mask->ChangeRepresentation(Representation::Integer32()); |
| 12136 mask->ClearFlag(HValue::kCanOverflow); |
| 12137 |
| 12138 HValue* bucket = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); |
| 12139 |
| 12140 // BuildHashToEntry |
| 12141 HValue* entry_index = AddUncasted<HAdd>(start_index, bucket); |
| 12142 entry_index->ClearFlag(HValue::kCanOverflow); |
| 12143 HValue* entry = |
| 12144 Add<HLoadKeyed>(table, entry_index, static_cast<HValue*>(NULL), |
| 12145 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 12146 entry->set_type(HType::Smi()); |
12165 | 12147 |
12166 Push(entry); | 12148 Push(entry); |
12167 | 12149 |
12168 LoopBuilder loop(this); | 12150 LoopBuilder loop(this); |
12169 loop.BeginBody(1); | 12151 loop.BeginBody(1); |
12170 | 12152 |
12171 entry = Pop(); | 12153 entry = Pop(); |
12172 | 12154 |
12173 { | 12155 { |
12174 IfBuilder if_not_found(this); | 12156 IfBuilder if_not_found(this); |
12175 if_not_found.If<HCompareNumericAndBranch>( | 12157 if_not_found.If<HCompareNumericAndBranch>(entry, not_found, Token::EQ); |
12176 entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ); | |
12177 if_not_found.Then(); | 12158 if_not_found.Then(); |
12178 Push(entry); | 12159 Push(entry); |
12179 loop.Break(); | 12160 loop.Break(); |
12180 } | 12161 } |
12181 | 12162 |
12182 HValue* key_index = | 12163 // BuildEntryToIndex |
12183 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets); | 12164 HValue* key_index = AddUncasted<HMul>(entry, entry_size); |
12184 HValue* candidate_key = Add<HLoadKeyed>( | 12165 key_index->ClearFlag(HValue::kCanOverflow); |
12185 table, key_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 12166 key_index = AddUncasted<HAdd>(key_index, key_start); |
| 12167 key_index->ClearFlag(HValue::kCanOverflow); |
| 12168 // BuildKeyAt |
| 12169 HValue* candidate_key = |
| 12170 Add<HLoadKeyed>(table, key_index, static_cast<HValue*>(NULL), |
| 12171 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
12186 | 12172 |
12187 { | 12173 { |
12188 IfBuilder if_keys_equal(this); | 12174 IfBuilder if_keys_equal(this); |
12189 if_keys_equal.If<HIsStringAndBranch>(candidate_key); | 12175 if_keys_equal.If<HIsStringAndBranch>(candidate_key); |
12190 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key, | 12176 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key, |
12191 Token::EQ_STRICT); | 12177 Token::EQ_STRICT); |
12192 if_keys_equal.Then(); | 12178 if_keys_equal.Then(); |
12193 Push(key_index); | 12179 Push(key_index); |
12194 loop.Break(); | 12180 loop.Break(); |
12195 } | 12181 } |
12196 | 12182 |
12197 // BuildChainAt | 12183 // BuildChainAt |
12198 HValue* chain_index = AddUncasted<HAdd>( | 12184 HValue* chain_index = AddUncasted<HMul>(entry, entry_size); |
12199 key_index, Add<HConstant>(CollectionType::kChainOffset)); | 12185 chain_index->ClearFlag(HValue::kCanOverflow); |
| 12186 chain_index = AddUncasted<HAdd>(chain_index, key_start); |
| 12187 chain_index->ClearFlag(HValue::kCanOverflow); |
| 12188 chain_index = AddUncasted<HAdd>(chain_index, chain_offset); |
12200 chain_index->ClearFlag(HValue::kCanOverflow); | 12189 chain_index->ClearFlag(HValue::kCanOverflow); |
12201 entry = Add<HLoadKeyed>(table, chain_index, static_cast<HValue*>(NULL), | 12190 entry = Add<HLoadKeyed>(table, chain_index, static_cast<HValue*>(NULL), |
12202 FAST_ELEMENTS); | 12191 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
12203 entry->set_type(HType::Smi()); | 12192 entry->set_type(HType::Smi()); |
12204 Push(entry); | 12193 Push(entry); |
12205 | 12194 |
12206 loop.EndBody(); | 12195 loop.EndBody(); |
12207 | 12196 |
12208 return Pop(); | 12197 return Pop(); |
12209 } | 12198 } |
12210 | 12199 |
12211 | 12200 |
12212 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) { | 12201 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12326 call, Runtime::FunctionForId(Runtime::kMapHas)); | 12315 call, Runtime::FunctionForId(Runtime::kMapHas)); |
12327 } | 12316 } |
12328 | 12317 |
12329 | 12318 |
12330 void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) { | 12319 void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) { |
12331 BuildJSCollectionHas<OrderedHashSet>( | 12320 BuildJSCollectionHas<OrderedHashSet>( |
12332 call, Runtime::FunctionForId(Runtime::kSetHas)); | 12321 call, Runtime::FunctionForId(Runtime::kSetHas)); |
12333 } | 12322 } |
12334 | 12323 |
12335 | 12324 |
12336 template <typename CollectionType> | |
12337 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableAddEntry( | |
12338 HValue* table, HValue* key, HValue* hash, | |
12339 HIfContinuation* join_continuation) { | |
12340 HValue* num_buckets = Add<HLoadNamedField>( | |
12341 table, static_cast<HValue*>(NULL), | |
12342 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); | |
12343 HValue* capacity = AddUncasted<HMul>( | |
12344 num_buckets, Add<HConstant>(CollectionType::kLoadFactor)); | |
12345 capacity->ClearFlag(HValue::kCanOverflow); | |
12346 HValue* num_elements = Add<HLoadNamedField>( | |
12347 table, static_cast<HValue*>(NULL), | |
12348 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>()); | |
12349 HValue* num_deleted = Add<HLoadNamedField>( | |
12350 table, static_cast<HValue*>(NULL), | |
12351 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | |
12352 CollectionType>()); | |
12353 HValue* used = AddUncasted<HAdd>(num_elements, num_deleted); | |
12354 used->ClearFlag(HValue::kCanOverflow); | |
12355 IfBuilder if_space_available(this); | |
12356 if_space_available.If<HCompareNumericAndBranch>(capacity, used, Token::GT); | |
12357 if_space_available.Then(); | |
12358 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets); | |
12359 HValue* entry = used; | |
12360 HValue* key_index = | |
12361 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets); | |
12362 | |
12363 HValue* bucket_index = AddUncasted<HAdd>( | |
12364 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex)); | |
12365 bucket_index->ClearFlag(HValue::kCanOverflow); | |
12366 HValue* chain_entry = Add<HLoadKeyed>( | |
12367 table, bucket_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
12368 chain_entry->set_type(HType::Smi()); | |
12369 | |
12370 HValue* chain_index = AddUncasted<HAdd>( | |
12371 key_index, Add<HConstant>(CollectionType::kChainOffset)); | |
12372 | |
12373 Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS); | |
12374 Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS); | |
12375 Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS); | |
12376 | |
12377 HValue* new_num_elements = | |
12378 AddUncasted<HAdd>(num_elements, graph()->GetConstant1()); | |
12379 new_num_elements->ClearFlag(HValue::kCanOverflow); | |
12380 Add<HStoreNamedField>( | |
12381 table, | |
12382 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(), | |
12383 new_num_elements); | |
12384 if_space_available.JoinContinuation(join_continuation); | |
12385 return key_index; | |
12386 } | |
12387 | |
12388 | |
12389 void HOptimizedGraphBuilder::GenerateMapSet(CallRuntime* call) { | |
12390 DCHECK(call->arguments()->length() == 3); | |
12391 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | |
12392 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | |
12393 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | |
12394 HValue* value = Pop(); | |
12395 HValue* key = Pop(); | |
12396 HValue* receiver = Pop(); | |
12397 | |
12398 NoObservableSideEffectsScope no_effects(this); | |
12399 | |
12400 HIfContinuation return_or_call_runtime_continuation( | |
12401 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | |
12402 HIfContinuation got_string_hash; | |
12403 HValue* hash = | |
12404 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); | |
12405 IfBuilder string_checker(this, &got_string_hash); | |
12406 string_checker.Then(); | |
12407 { | |
12408 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | |
12409 HObjectAccess::ForJSCollectionTable()); | |
12410 HValue* key_index = | |
12411 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash); | |
12412 { | |
12413 IfBuilder if_found(this); | |
12414 if_found.If<HCompareNumericAndBranch>( | |
12415 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE); | |
12416 if_found.Then(); | |
12417 { | |
12418 HValue* value_index = AddUncasted<HAdd>( | |
12419 key_index, Add<HConstant>(OrderedHashMap::kValueOffset)); | |
12420 value_index->ClearFlag(HValue::kCanOverflow); | |
12421 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS); | |
12422 } | |
12423 if_found.Else(); | |
12424 { | |
12425 HIfContinuation did_add(graph()->CreateBasicBlock(), | |
12426 graph()->CreateBasicBlock()); | |
12427 HValue* key_index = BuildOrderedHashTableAddEntry<OrderedHashMap>( | |
12428 table, key, hash, &did_add); | |
12429 IfBuilder if_did_add(this, &did_add); | |
12430 if_did_add.Then(); | |
12431 { | |
12432 HValue* value_index = AddUncasted<HAdd>( | |
12433 key_index, Add<HConstant>(OrderedHashMap::kValueOffset)); | |
12434 value_index->ClearFlag(HValue::kCanOverflow); | |
12435 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS); | |
12436 } | |
12437 if_did_add.JoinContinuation(&return_or_call_runtime_continuation); | |
12438 } | |
12439 } | |
12440 } | |
12441 string_checker.JoinContinuation(&return_or_call_runtime_continuation); | |
12442 | |
12443 { | |
12444 IfBuilder return_or_call_runtime(this, | |
12445 &return_or_call_runtime_continuation); | |
12446 return_or_call_runtime.Then(); | |
12447 Push(receiver); | |
12448 return_or_call_runtime.Else(); | |
12449 Add<HPushArguments>(receiver, key, value); | |
12450 Push(Add<HCallRuntime>(call->name(), | |
12451 Runtime::FunctionForId(Runtime::kMapSet), 3)); | |
12452 } | |
12453 | |
12454 return ast_context()->ReturnValue(Pop()); | |
12455 } | |
12456 | |
12457 | |
12458 void HOptimizedGraphBuilder::GenerateSetAdd(CallRuntime* call) { | |
12459 DCHECK(call->arguments()->length() == 2); | |
12460 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | |
12461 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | |
12462 HValue* key = Pop(); | |
12463 HValue* receiver = Pop(); | |
12464 | |
12465 NoObservableSideEffectsScope no_effects(this); | |
12466 | |
12467 HIfContinuation return_or_call_runtime_continuation( | |
12468 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | |
12469 HIfContinuation got_string_hash; | |
12470 HValue* hash = | |
12471 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); | |
12472 IfBuilder string_checker(this, &got_string_hash); | |
12473 string_checker.Then(); | |
12474 { | |
12475 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | |
12476 HObjectAccess::ForJSCollectionTable()); | |
12477 HValue* key_index = | |
12478 BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash); | |
12479 { | |
12480 IfBuilder if_not_found(this); | |
12481 if_not_found.If<HCompareNumericAndBranch>( | |
12482 key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ); | |
12483 if_not_found.Then(); | |
12484 BuildOrderedHashTableAddEntry<OrderedHashSet>( | |
12485 table, key, hash, &return_or_call_runtime_continuation); | |
12486 } | |
12487 } | |
12488 string_checker.JoinContinuation(&return_or_call_runtime_continuation); | |
12489 | |
12490 { | |
12491 IfBuilder return_or_call_runtime(this, | |
12492 &return_or_call_runtime_continuation); | |
12493 return_or_call_runtime.Then(); | |
12494 Push(receiver); | |
12495 return_or_call_runtime.Else(); | |
12496 Add<HPushArguments>(receiver, key); | |
12497 Push(Add<HCallRuntime>(call->name(), | |
12498 Runtime::FunctionForId(Runtime::kSetAdd), 2)); | |
12499 } | |
12500 | |
12501 return ast_context()->ReturnValue(Pop()); | |
12502 } | |
12503 | |
12504 | |
12505 template <typename CollectionType> | |
12506 void HOptimizedGraphBuilder::BuildJSCollectionDelete( | |
12507 CallRuntime* call, const Runtime::Function* c_function) { | |
12508 DCHECK(call->arguments()->length() == 2); | |
12509 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | |
12510 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | |
12511 HValue* key = Pop(); | |
12512 HValue* receiver = Pop(); | |
12513 | |
12514 NoObservableSideEffectsScope no_effects(this); | |
12515 | |
12516 HIfContinuation return_or_call_runtime_continuation( | |
12517 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | |
12518 HIfContinuation got_string_hash; | |
12519 HValue* hash = | |
12520 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); | |
12521 IfBuilder string_checker(this, &got_string_hash); | |
12522 string_checker.Then(); | |
12523 { | |
12524 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | |
12525 HObjectAccess::ForJSCollectionTable()); | |
12526 HValue* key_index = | |
12527 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash); | |
12528 { | |
12529 IfBuilder if_found(this); | |
12530 if_found.If<HCompareNumericAndBranch>( | |
12531 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE); | |
12532 if_found.Then(); | |
12533 { | |
12534 // If we're removing an element, we might need to shrink. | |
12535 // If we do need to shrink, we'll be bailing out to the runtime. | |
12536 HValue* num_elements = Add<HLoadNamedField>( | |
12537 table, static_cast<HValue*>(NULL), | |
12538 HObjectAccess::ForOrderedHashTableNumberOfElements< | |
12539 CollectionType>()); | |
12540 num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1()); | |
12541 | |
12542 HValue* num_buckets = Add<HLoadNamedField>( | |
12543 table, static_cast<HValue*>(NULL), | |
12544 HObjectAccess::ForOrderedHashTableNumberOfBuckets< | |
12545 CollectionType>()); | |
12546 // threshold is capacity >> 2; we simplify this to num_buckets >> 1 | |
12547 // since kLoadFactor is 2. | |
12548 STATIC_ASSERT(CollectionType::kLoadFactor == 2); | |
12549 HValue* threshold = | |
12550 AddUncasted<HShr>(num_buckets, graph()->GetConstant1()); | |
12551 | |
12552 IfBuilder if_need_not_shrink(this); | |
12553 if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold, | |
12554 Token::GTE); | |
12555 if_need_not_shrink.Then(); | |
12556 { | |
12557 Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(), | |
12558 FAST_ELEMENTS); | |
12559 | |
12560 // For maps, also need to clear the value. | |
12561 if (CollectionType::kChainOffset > 1) { | |
12562 HValue* value_index = | |
12563 AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | |
12564 Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(), | |
12565 FAST_ELEMENTS); | |
12566 } | |
12567 STATIC_ASSERT(CollectionType::kChainOffset <= 2); | |
12568 | |
12569 HValue* num_deleted = Add<HLoadNamedField>( | |
12570 table, static_cast<HValue*>(NULL), | |
12571 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | |
12572 CollectionType>()); | |
12573 num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1()); | |
12574 Add<HStoreNamedField>( | |
12575 table, HObjectAccess::ForOrderedHashTableNumberOfElements< | |
12576 CollectionType>(), | |
12577 num_elements); | |
12578 Add<HStoreNamedField>( | |
12579 table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | |
12580 CollectionType>(), | |
12581 num_deleted); | |
12582 Push(graph()->GetConstantTrue()); | |
12583 } | |
12584 if_need_not_shrink.JoinContinuation( | |
12585 &return_or_call_runtime_continuation); | |
12586 } | |
12587 if_found.Else(); | |
12588 { | |
12589 // Not found, so we're done. | |
12590 Push(graph()->GetConstantFalse()); | |
12591 } | |
12592 } | |
12593 } | |
12594 string_checker.JoinContinuation(&return_or_call_runtime_continuation); | |
12595 | |
12596 { | |
12597 IfBuilder return_or_call_runtime(this, | |
12598 &return_or_call_runtime_continuation); | |
12599 return_or_call_runtime.Then(); | |
12600 return_or_call_runtime.Else(); | |
12601 Add<HPushArguments>(receiver, key); | |
12602 Push(Add<HCallRuntime>(call->name(), c_function, 2)); | |
12603 } | |
12604 | |
12605 return ast_context()->ReturnValue(Pop()); | |
12606 } | |
12607 | |
12608 | |
12609 void HOptimizedGraphBuilder::GenerateMapDelete(CallRuntime* call) { | |
12610 BuildJSCollectionDelete<OrderedHashMap>( | |
12611 call, Runtime::FunctionForId(Runtime::kMapDelete)); | |
12612 } | |
12613 | |
12614 | |
12615 void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) { | |
12616 BuildJSCollectionDelete<OrderedHashSet>( | |
12617 call, Runtime::FunctionForId(Runtime::kSetDelete)); | |
12618 } | |
12619 | |
12620 | |
12621 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) { | 12325 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) { |
12622 DCHECK(call->arguments()->length() == 1); | 12326 DCHECK(call->arguments()->length() == 1); |
12623 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12327 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
12624 HValue* receiver = Pop(); | 12328 HValue* receiver = Pop(); |
12625 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12329 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), |
12626 HObjectAccess::ForJSCollectionTable()); | 12330 HObjectAccess::ForJSCollectionTable()); |
12627 HInstruction* result = New<HLoadNamedField>( | 12331 HInstruction* result = New<HLoadNamedField>( |
12628 table, static_cast<HValue*>(NULL), | 12332 table, static_cast<HValue*>(NULL), |
12629 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>()); | 12333 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>()); |
12630 return ast_context()->ReturnInstruction(result, call->id()); | 12334 return ast_context()->ReturnInstruction(result, call->id()); |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13316 if (ShouldProduceTraceOutput()) { | 13020 if (ShouldProduceTraceOutput()) { |
13317 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13021 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13318 } | 13022 } |
13319 | 13023 |
13320 #ifdef DEBUG | 13024 #ifdef DEBUG |
13321 graph_->Verify(false); // No full verify. | 13025 graph_->Verify(false); // No full verify. |
13322 #endif | 13026 #endif |
13323 } | 13027 } |
13324 | 13028 |
13325 } } // namespace v8::internal | 13029 } } // namespace v8::internal |
OLD | NEW |