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

Side by Side Diff: src/hydrogen.cc

Issue 782073002: Optimize add/set/delete operations for string keys in Maps and Sets (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed patch Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
12117 template <typename CollectionType> 12155 template <typename CollectionType>
12118 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table, 12156 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table,
12119 HValue* key, 12157 HValue* key,
12120 HValue* hash) { 12158 HValue* hash) {
12121 HValue* num_buckets = Add<HLoadNamedField>( 12159 HValue* num_buckets = Add<HLoadNamedField>(
12122 table, static_cast<HValue*>(NULL), 12160 table, static_cast<HValue*>(NULL),
12123 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); 12161 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
12124 12162
12125 // Some things that won't change inside the loop 12163 HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash,
12126 HValue* not_found = Add<HConstant>(CollectionType::kNotFound); 12164 num_buckets);
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());
12147 12165
12148 Push(entry); 12166 Push(entry);
12149 12167
12150 LoopBuilder loop(this); 12168 LoopBuilder loop(this);
12151 loop.BeginBody(1); 12169 loop.BeginBody(1);
12152 12170
12153 entry = Pop(); 12171 entry = Pop();
12154 12172
12155 { 12173 {
12156 IfBuilder if_not_found(this); 12174 IfBuilder if_not_found(this);
12157 if_not_found.If<HCompareNumericAndBranch>(entry, not_found, Token::EQ); 12175 if_not_found.If<HCompareNumericAndBranch>(
12176 entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ);
12158 if_not_found.Then(); 12177 if_not_found.Then();
12159 Push(entry); 12178 Push(entry);
12160 loop.Break(); 12179 loop.Break();
12161 } 12180 }
12162 12181
12163 // BuildEntryToIndex 12182 HValue* key_index =
12164 HValue* key_index = AddUncasted<HMul>(entry, entry_size); 12183 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
12165 key_index->ClearFlag(HValue::kCanOverflow); 12184 HValue* candidate_key = Add<HLoadKeyed>(
12166 key_index = AddUncasted<HAdd>(key_index, key_start); 12185 table, key_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
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);
12172 12186
12173 { 12187 {
12174 IfBuilder if_keys_equal(this); 12188 IfBuilder if_keys_equal(this);
12175 if_keys_equal.If<HIsStringAndBranch>(candidate_key); 12189 if_keys_equal.If<HIsStringAndBranch>(candidate_key);
12176 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key, 12190 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key,
12177 Token::EQ_STRICT); 12191 Token::EQ_STRICT);
12178 if_keys_equal.Then(); 12192 if_keys_equal.Then();
12179 Push(key_index); 12193 Push(key_index);
12180 loop.Break(); 12194 loop.Break();
12181 } 12195 }
12182 12196
12183 // BuildChainAt 12197 // BuildChainAt
12184 HValue* chain_index = AddUncasted<HMul>(entry, entry_size); 12198 HValue* chain_index = AddUncasted<HAdd>(
12185 chain_index->ClearFlag(HValue::kCanOverflow); 12199 key_index, Add<HConstant>(CollectionType::kChainOffset));
12186 chain_index = AddUncasted<HAdd>(chain_index, key_start);
12187 chain_index->ClearFlag(HValue::kCanOverflow);
12188 chain_index = AddUncasted<HAdd>(chain_index, chain_offset);
12189 chain_index->ClearFlag(HValue::kCanOverflow); 12200 chain_index->ClearFlag(HValue::kCanOverflow);
12190 entry = Add<HLoadKeyed>(table, chain_index, static_cast<HValue*>(NULL), 12201 entry = Add<HLoadKeyed>(table, chain_index, static_cast<HValue*>(NULL),
12191 FAST_ELEMENTS, ALLOW_RETURN_HOLE); 12202 FAST_ELEMENTS);
12192 entry->set_type(HType::Smi()); 12203 entry->set_type(HType::Smi());
12193 Push(entry); 12204 Push(entry);
12194 12205
12195 loop.EndBody(); 12206 loop.EndBody();
12196 12207
12197 return Pop(); 12208 return Pop();
12198 } 12209 }
12199 12210
12200 12211
12201 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) { 12212 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
12315 call, Runtime::FunctionForId(Runtime::kMapHas)); 12326 call, Runtime::FunctionForId(Runtime::kMapHas));
12316 } 12327 }
12317 12328
12318 12329
12319 void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) { 12330 void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) {
12320 BuildJSCollectionHas<OrderedHashSet>( 12331 BuildJSCollectionHas<OrderedHashSet>(
12321 call, Runtime::FunctionForId(Runtime::kSetHas)); 12332 call, Runtime::FunctionForId(Runtime::kSetHas));
12322 } 12333 }
12323 12334
12324 12335
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 chain_index->ClearFlag(HValue::kCanOverflow);
12373
12374 Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS);
12375 Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS);
12376 Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS);
12377
12378 HValue* new_num_elements =
12379 AddUncasted<HAdd>(num_elements, graph()->GetConstant1());
12380 new_num_elements->ClearFlag(HValue::kCanOverflow);
12381 Add<HStoreNamedField>(
12382 table,
12383 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(),
12384 new_num_elements);
12385 if_space_available.JoinContinuation(join_continuation);
12386 return key_index;
12387 }
12388
12389
12390 void HOptimizedGraphBuilder::GenerateMapSet(CallRuntime* call) {
12391 DCHECK(call->arguments()->length() == 3);
12392 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12393 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12394 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
12395 HValue* value = Pop();
12396 HValue* key = Pop();
12397 HValue* receiver = Pop();
12398
12399 NoObservableSideEffectsScope no_effects(this);
12400
12401 HIfContinuation return_or_call_runtime_continuation(
12402 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12403 HIfContinuation got_string_hash;
12404 HValue* hash =
12405 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12406 IfBuilder string_checker(this, &got_string_hash);
12407 string_checker.Then();
12408 {
12409 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
12410 HObjectAccess::ForJSCollectionTable());
12411 HValue* key_index =
12412 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
12413 {
12414 IfBuilder if_found(this);
12415 if_found.If<HCompareNumericAndBranch>(
12416 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
12417 if_found.Then();
12418 {
12419 HValue* value_index = AddUncasted<HAdd>(
12420 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12421 value_index->ClearFlag(HValue::kCanOverflow);
12422 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
12423 }
12424 if_found.Else();
12425 {
12426 HIfContinuation did_add(graph()->CreateBasicBlock(),
12427 graph()->CreateBasicBlock());
12428 HValue* key_index = BuildOrderedHashTableAddEntry<OrderedHashMap>(
12429 table, key, hash, &did_add);
12430 IfBuilder if_did_add(this, &did_add);
12431 if_did_add.Then();
12432 {
12433 HValue* value_index = AddUncasted<HAdd>(
12434 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12435 value_index->ClearFlag(HValue::kCanOverflow);
12436 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
12437 }
12438 if_did_add.JoinContinuation(&return_or_call_runtime_continuation);
12439 }
12440 }
12441 }
12442 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12443
12444 {
12445 IfBuilder return_or_call_runtime(this,
12446 &return_or_call_runtime_continuation);
12447 return_or_call_runtime.Then();
12448 Push(receiver);
12449 return_or_call_runtime.Else();
12450 Add<HPushArguments>(receiver, key, value);
12451 Push(Add<HCallRuntime>(call->name(),
12452 Runtime::FunctionForId(Runtime::kMapSet), 3));
12453 }
12454
12455 return ast_context()->ReturnValue(Pop());
12456 }
12457
12458
12459 void HOptimizedGraphBuilder::GenerateSetAdd(CallRuntime* call) {
12460 DCHECK(call->arguments()->length() == 2);
12461 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12462 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12463 HValue* key = Pop();
12464 HValue* receiver = Pop();
12465
12466 NoObservableSideEffectsScope no_effects(this);
12467
12468 HIfContinuation return_or_call_runtime_continuation(
12469 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12470 HIfContinuation got_string_hash;
12471 HValue* hash =
12472 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12473 IfBuilder string_checker(this, &got_string_hash);
12474 string_checker.Then();
12475 {
12476 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
12477 HObjectAccess::ForJSCollectionTable());
12478 HValue* key_index =
12479 BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash);
12480 {
12481 IfBuilder if_not_found(this);
12482 if_not_found.If<HCompareNumericAndBranch>(
12483 key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ);
12484 if_not_found.Then();
12485 BuildOrderedHashTableAddEntry<OrderedHashSet>(
12486 table, key, hash, &return_or_call_runtime_continuation);
12487 }
12488 }
12489 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12490
12491 {
12492 IfBuilder return_or_call_runtime(this,
12493 &return_or_call_runtime_continuation);
12494 return_or_call_runtime.Then();
12495 Push(receiver);
12496 return_or_call_runtime.Else();
12497 Add<HPushArguments>(receiver, key);
12498 Push(Add<HCallRuntime>(call->name(),
12499 Runtime::FunctionForId(Runtime::kSetAdd), 2));
12500 }
12501
12502 return ast_context()->ReturnValue(Pop());
12503 }
12504
12505
12506 template <typename CollectionType>
12507 void HOptimizedGraphBuilder::BuildJSCollectionDelete(
12508 CallRuntime* call, const Runtime::Function* c_function) {
12509 DCHECK(call->arguments()->length() == 2);
12510 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12511 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12512 HValue* key = Pop();
12513 HValue* receiver = Pop();
12514
12515 NoObservableSideEffectsScope no_effects(this);
12516
12517 HIfContinuation return_or_call_runtime_continuation(
12518 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12519 HIfContinuation got_string_hash;
12520 HValue* hash =
12521 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12522 IfBuilder string_checker(this, &got_string_hash);
12523 string_checker.Then();
12524 {
12525 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
12526 HObjectAccess::ForJSCollectionTable());
12527 HValue* key_index =
12528 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
12529 {
12530 IfBuilder if_found(this);
12531 if_found.If<HCompareNumericAndBranch>(
12532 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
12533 if_found.Then();
12534 {
12535 // If we're removing an element, we might need to shrink.
12536 // If we do need to shrink, we'll be bailing out to the runtime.
12537 HValue* num_elements = Add<HLoadNamedField>(
12538 table, static_cast<HValue*>(NULL),
12539 HObjectAccess::ForOrderedHashTableNumberOfElements<
12540 CollectionType>());
12541 num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1());
12542 num_elements->ClearFlag(HValue::kCanOverflow);
12543
12544 HValue* num_buckets = Add<HLoadNamedField>(
12545 table, static_cast<HValue*>(NULL),
12546 HObjectAccess::ForOrderedHashTableNumberOfBuckets<
12547 CollectionType>());
12548 // threshold is capacity >> 2; we simplify this to num_buckets >> 1
12549 // since kLoadFactor is 2.
12550 STATIC_ASSERT(CollectionType::kLoadFactor == 2);
12551 HValue* threshold =
12552 AddUncasted<HShr>(num_buckets, graph()->GetConstant1());
12553
12554 IfBuilder if_need_not_shrink(this);
12555 if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold,
12556 Token::GTE);
12557 if_need_not_shrink.Then();
12558 {
12559 Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(),
12560 FAST_ELEMENTS);
12561
12562 // For maps, also need to clear the value.
12563 if (CollectionType::kChainOffset > 1) {
12564 HValue* value_index =
12565 AddUncasted<HAdd>(key_index, graph()->GetConstant1());
12566 value_index->ClearFlag(HValue::kCanOverflow);
12567 Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(),
12568 FAST_ELEMENTS);
12569 }
12570 STATIC_ASSERT(CollectionType::kChainOffset <= 2);
12571
12572 HValue* num_deleted = Add<HLoadNamedField>(
12573 table, static_cast<HValue*>(NULL),
12574 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12575 CollectionType>());
12576 num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1());
12577 num_deleted->ClearFlag(HValue::kCanOverflow);
12578 Add<HStoreNamedField>(
12579 table, HObjectAccess::ForOrderedHashTableNumberOfElements<
12580 CollectionType>(),
12581 num_elements);
12582 Add<HStoreNamedField>(
12583 table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12584 CollectionType>(),
12585 num_deleted);
12586 Push(graph()->GetConstantTrue());
12587 }
12588 if_need_not_shrink.JoinContinuation(
12589 &return_or_call_runtime_continuation);
12590 }
12591 if_found.Else();
12592 {
12593 // Not found, so we're done.
12594 Push(graph()->GetConstantFalse());
12595 }
12596 }
12597 }
12598 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12599
12600 {
12601 IfBuilder return_or_call_runtime(this,
12602 &return_or_call_runtime_continuation);
12603 return_or_call_runtime.Then();
12604 return_or_call_runtime.Else();
12605 Add<HPushArguments>(receiver, key);
12606 Push(Add<HCallRuntime>(call->name(), c_function, 2));
12607 }
12608
12609 return ast_context()->ReturnValue(Pop());
12610 }
12611
12612
12613 void HOptimizedGraphBuilder::GenerateMapDelete(CallRuntime* call) {
12614 BuildJSCollectionDelete<OrderedHashMap>(
12615 call, Runtime::FunctionForId(Runtime::kMapDelete));
12616 }
12617
12618
12619 void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) {
12620 BuildJSCollectionDelete<OrderedHashSet>(
12621 call, Runtime::FunctionForId(Runtime::kSetDelete));
12622 }
12623
12624
12325 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) { 12625 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) {
12326 DCHECK(call->arguments()->length() == 1); 12626 DCHECK(call->arguments()->length() == 1);
12327 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12627 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12328 HValue* receiver = Pop(); 12628 HValue* receiver = Pop();
12329 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), 12629 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
12330 HObjectAccess::ForJSCollectionTable()); 12630 HObjectAccess::ForJSCollectionTable());
12331 HInstruction* result = New<HLoadNamedField>( 12631 HInstruction* result = New<HLoadNamedField>(
12332 table, static_cast<HValue*>(NULL), 12632 table, static_cast<HValue*>(NULL),
12333 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>()); 12633 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>());
12334 return ast_context()->ReturnInstruction(result, call->id()); 12634 return ast_context()->ReturnInstruction(result, call->id());
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
13068 if (ShouldProduceTraceOutput()) { 13368 if (ShouldProduceTraceOutput()) {
13069 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13369 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13070 } 13370 }
13071 13371
13072 #ifdef DEBUG 13372 #ifdef DEBUG
13073 graph_->Verify(false); // No full verify. 13373 graph_->Verify(false); // No full verify.
13074 #endif 13374 #endif
13075 } 13375 }
13076 13376
13077 } } // namespace v8::internal 13377 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698