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

Side by Side Diff: src/hydrogen.cc

Issue 777663003: 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: 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
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
12325 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) { 12621 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) {
12326 DCHECK(call->arguments()->length() == 1); 12622 DCHECK(call->arguments()->length() == 1);
12327 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12623 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12328 HValue* receiver = Pop(); 12624 HValue* receiver = Pop();
12329 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), 12625 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
12330 HObjectAccess::ForJSCollectionTable()); 12626 HObjectAccess::ForJSCollectionTable());
12331 HInstruction* result = New<HLoadNamedField>( 12627 HInstruction* result = New<HLoadNamedField>(
12332 table, static_cast<HValue*>(NULL), 12628 table, static_cast<HValue*>(NULL),
12333 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>()); 12629 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>());
12334 return ast_context()->ReturnInstruction(result, call->id()); 12630 return ast_context()->ReturnInstruction(result, call->id());
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
13020 if (ShouldProduceTraceOutput()) { 13316 if (ShouldProduceTraceOutput()) {
13021 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13317 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13022 } 13318 }
13023 13319
13024 #ifdef DEBUG 13320 #ifdef DEBUG
13025 graph_->Verify(false); // No full verify. 13321 graph_->Verify(false); // No full verify.
13026 #endif 13322 #endif
13027 } 13323 }
13028 13324
13029 } } // namespace v8::internal 13325 } } // 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