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

Side by Side Diff: src/hydrogen.cc

Issue 947683002: Reimplement Maps and Sets in JS (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Merged to master Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('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 12037 matching lines...) Expand 10 before | Expand all | Expand 10 after
12048 DCHECK(call->arguments()->length() == 1); 12048 DCHECK(call->arguments()->length() == 1);
12049 Visit(call->arguments()->at(0)); 12049 Visit(call->arguments()->at(0));
12050 } 12050 }
12051 12051
12052 12052
12053 void HOptimizedGraphBuilder::GenerateUnlikely(CallRuntime* call) { 12053 void HOptimizedGraphBuilder::GenerateUnlikely(CallRuntime* call) {
12054 return GenerateLikely(call); 12054 return GenerateLikely(call);
12055 } 12055 }
12056 12056
12057 12057
12058 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToBucket( 12058 void HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) {
12059 HValue* hash, HValue* num_buckets) { 12059 DCHECK(call->arguments()->length() == 2);
12060 HValue* mask = AddUncasted<HSub>(num_buckets, graph()->GetConstant1()); 12060 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12061 mask->ChangeRepresentation(Representation::Integer32()); 12061 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12062 mask->ClearFlag(HValue::kCanOverflow); 12062 HValue* index = Pop();
12063 return AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); 12063 HValue* object = Pop();
12064 HInstruction* result = New<HLoadKeyed>(
12065 object, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE);
12066 return ast_context()->ReturnInstruction(result, call->id());
12064 } 12067 }
12065 12068
12066 12069
12067 template <typename CollectionType> 12070 void HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) {
12068 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToEntry(
12069 HValue* table, HValue* hash, HValue* num_buckets) {
12070 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets);
12071 HValue* entry_index = AddUncasted<HAdd>(
12072 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex));
12073 entry_index->ClearFlag(HValue::kCanOverflow);
12074 HValue* entry = Add<HLoadKeyed>(table, entry_index, nullptr, FAST_ELEMENTS);
12075 entry->set_type(HType::Smi());
12076 return entry;
12077 }
12078
12079
12080 template <typename CollectionType>
12081 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableEntryToIndex(
12082 HValue* entry, HValue* num_buckets) {
12083 HValue* index =
12084 AddUncasted<HMul>(entry, Add<HConstant>(CollectionType::kEntrySize));
12085 index->ClearFlag(HValue::kCanOverflow);
12086 index = AddUncasted<HAdd>(index, num_buckets);
12087 index->ClearFlag(HValue::kCanOverflow);
12088 index = AddUncasted<HAdd>(
12089 index, Add<HConstant>(CollectionType::kHashTableStartIndex));
12090 index->ClearFlag(HValue::kCanOverflow);
12091 return index;
12092 }
12093
12094
12095 template <typename CollectionType>
12096 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table,
12097 HValue* key,
12098 HValue* hash) {
12099 HValue* num_buckets = Add<HLoadNamedField>(
12100 table, nullptr,
12101 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
12102
12103 HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash,
12104 num_buckets);
12105
12106 Push(entry);
12107
12108 LoopBuilder loop(this);
12109 loop.BeginBody(1);
12110
12111 entry = Pop();
12112
12113 {
12114 IfBuilder if_not_found(this);
12115 if_not_found.If<HCompareNumericAndBranch>(
12116 entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ);
12117 if_not_found.Then();
12118 Push(entry);
12119 loop.Break();
12120 }
12121
12122 HValue* key_index =
12123 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
12124 HValue* candidate_key =
12125 Add<HLoadKeyed>(table, key_index, nullptr, FAST_ELEMENTS);
12126
12127 {
12128 IfBuilder if_keys_equal(this);
12129 if_keys_equal.If<HIsStringAndBranch>(candidate_key);
12130 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key,
12131 Token::EQ_STRICT);
12132 if_keys_equal.Then();
12133 Push(key_index);
12134 loop.Break();
12135 }
12136
12137 // BuildChainAt
12138 HValue* chain_index = AddUncasted<HAdd>(
12139 key_index, Add<HConstant>(CollectionType::kChainOffset));
12140 chain_index->ClearFlag(HValue::kCanOverflow);
12141 entry = Add<HLoadKeyed>(table, chain_index, nullptr, FAST_ELEMENTS);
12142 entry->set_type(HType::Smi());
12143 Push(entry);
12144
12145 loop.EndBody();
12146
12147 return Pop();
12148 }
12149
12150
12151 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) {
12152 DCHECK(call->arguments()->length() == 2);
12153 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12154 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12155 HValue* key = Pop();
12156 HValue* receiver = Pop();
12157
12158 NoObservableSideEffectsScope no_effects(this);
12159
12160 HIfContinuation continuation;
12161 HValue* hash =
12162 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation);
12163 {
12164 IfBuilder string_checker(this, &continuation);
12165 string_checker.Then();
12166 {
12167 HValue* table = Add<HLoadNamedField>(
12168 receiver, nullptr, HObjectAccess::ForJSCollectionTable());
12169 HValue* key_index =
12170 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
12171 IfBuilder if_found(this);
12172 if_found.If<HCompareNumericAndBranch>(
12173 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
12174 if_found.Then();
12175 {
12176 HValue* value_index = AddUncasted<HAdd>(
12177 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12178 value_index->ClearFlag(HValue::kCanOverflow);
12179 Push(Add<HLoadKeyed>(table, value_index, nullptr, FAST_ELEMENTS));
12180 }
12181 if_found.Else();
12182 Push(graph()->GetConstantUndefined());
12183 if_found.End();
12184 }
12185 string_checker.Else();
12186 {
12187 Add<HPushArguments>(receiver, key);
12188 Push(Add<HCallRuntime>(call->name(),
12189 Runtime::FunctionForId(Runtime::kMapGet), 2));
12190 }
12191 }
12192
12193 return ast_context()->ReturnValue(Pop());
12194 }
12195
12196
12197 HValue* HOptimizedGraphBuilder::BuildStringHashLoadIfIsStringAndHashComputed(
12198 HValue* object, HIfContinuation* continuation) {
12199 IfBuilder string_checker(this);
12200 string_checker.If<HIsStringAndBranch>(object);
12201 string_checker.And();
12202 HValue* hash = Add<HLoadNamedField>(object, nullptr,
12203 HObjectAccess::ForStringHashField());
12204 HValue* hash_not_computed_mask = Add<HConstant>(String::kHashNotComputedMask);
12205 HValue* hash_computed_test =
12206 AddUncasted<HBitwise>(Token::BIT_AND, hash, hash_not_computed_mask);
12207 string_checker.If<HCompareNumericAndBranch>(
12208 hash_computed_test, graph()->GetConstant0(), Token::EQ);
12209 string_checker.Then();
12210 HValue* shifted_hash =
12211 AddUncasted<HShr>(hash, Add<HConstant>(String::kHashShift));
12212 string_checker.CaptureContinuation(continuation);
12213 return shifted_hash;
12214 }
12215
12216
12217 template <typename CollectionType>
12218 void HOptimizedGraphBuilder::BuildJSCollectionHas(
12219 CallRuntime* call, const Runtime::Function* c_function) {
12220 DCHECK(call->arguments()->length() == 2);
12221 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12222 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12223 HValue* key = Pop();
12224 HValue* receiver = Pop();
12225
12226 NoObservableSideEffectsScope no_effects(this);
12227
12228 HIfContinuation continuation;
12229 HValue* hash =
12230 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation);
12231 {
12232 IfBuilder string_checker(this, &continuation);
12233 string_checker.Then();
12234 {
12235 HValue* table = Add<HLoadNamedField>(
12236 receiver, nullptr, HObjectAccess::ForJSCollectionTable());
12237 HValue* key_index =
12238 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
12239 {
12240 IfBuilder if_found(this);
12241 if_found.If<HCompareNumericAndBranch>(
12242 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
12243 if_found.Then();
12244 Push(graph()->GetConstantTrue());
12245 if_found.Else();
12246 Push(graph()->GetConstantFalse());
12247 }
12248 }
12249 string_checker.Else();
12250 {
12251 Add<HPushArguments>(receiver, key);
12252 Push(Add<HCallRuntime>(call->name(), c_function, 2));
12253 }
12254 }
12255
12256 return ast_context()->ReturnValue(Pop());
12257 }
12258
12259
12260 void HOptimizedGraphBuilder::GenerateMapHas(CallRuntime* call) {
12261 BuildJSCollectionHas<OrderedHashMap>(
12262 call, Runtime::FunctionForId(Runtime::kMapHas));
12263 }
12264
12265
12266 void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) {
12267 BuildJSCollectionHas<OrderedHashSet>(
12268 call, Runtime::FunctionForId(Runtime::kSetHas));
12269 }
12270
12271
12272 template <typename CollectionType>
12273 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableAddEntry(
12274 HValue* table, HValue* key, HValue* hash,
12275 HIfContinuation* join_continuation) {
12276 HValue* num_buckets = Add<HLoadNamedField>(
12277 table, nullptr,
12278 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
12279 HValue* capacity = AddUncasted<HMul>(
12280 num_buckets, Add<HConstant>(CollectionType::kLoadFactor));
12281 capacity->ClearFlag(HValue::kCanOverflow);
12282 HValue* num_elements = Add<HLoadNamedField>(
12283 table, nullptr,
12284 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>());
12285 HValue* num_deleted = Add<HLoadNamedField>(
12286 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12287 CollectionType>());
12288 HValue* used = AddUncasted<HAdd>(num_elements, num_deleted);
12289 used->ClearFlag(HValue::kCanOverflow);
12290 IfBuilder if_space_available(this);
12291 if_space_available.If<HCompareNumericAndBranch>(capacity, used, Token::GT);
12292 if_space_available.Then();
12293 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets);
12294 HValue* entry = used;
12295 HValue* key_index =
12296 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
12297
12298 HValue* bucket_index = AddUncasted<HAdd>(
12299 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex));
12300 bucket_index->ClearFlag(HValue::kCanOverflow);
12301 HValue* chain_entry =
12302 Add<HLoadKeyed>(table, bucket_index, nullptr, FAST_ELEMENTS);
12303 chain_entry->set_type(HType::Smi());
12304
12305 HValue* chain_index = AddUncasted<HAdd>(
12306 key_index, Add<HConstant>(CollectionType::kChainOffset));
12307 chain_index->ClearFlag(HValue::kCanOverflow);
12308
12309 Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS);
12310 Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS);
12311 Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS);
12312
12313 HValue* new_num_elements =
12314 AddUncasted<HAdd>(num_elements, graph()->GetConstant1());
12315 new_num_elements->ClearFlag(HValue::kCanOverflow);
12316 Add<HStoreNamedField>(
12317 table,
12318 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(),
12319 new_num_elements);
12320 if_space_available.JoinContinuation(join_continuation);
12321 return key_index;
12322 }
12323
12324
12325 void HOptimizedGraphBuilder::GenerateMapSet(CallRuntime* call) {
12326 DCHECK(call->arguments()->length() == 3); 12071 DCHECK(call->arguments()->length() == 3);
12327 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12072 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12328 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 12073 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12329 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 12074 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
12330 HValue* value = Pop(); 12075 HValue* value = Pop();
12331 HValue* key = Pop(); 12076 HValue* index = Pop();
12332 HValue* receiver = Pop(); 12077 HValue* object = Pop();
12333
12334 NoObservableSideEffectsScope no_effects(this); 12078 NoObservableSideEffectsScope no_effects(this);
12335 12079 Add<HStoreKeyed>(object, index, value, FAST_HOLEY_ELEMENTS);
12336 HIfContinuation return_or_call_runtime_continuation( 12080 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
12337 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12338 HIfContinuation got_string_hash;
12339 HValue* hash =
12340 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12341 IfBuilder string_checker(this, &got_string_hash);
12342 string_checker.Then();
12343 {
12344 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12345 HObjectAccess::ForJSCollectionTable());
12346 HValue* key_index =
12347 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
12348 {
12349 IfBuilder if_found(this);
12350 if_found.If<HCompareNumericAndBranch>(
12351 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
12352 if_found.Then();
12353 {
12354 HValue* value_index = AddUncasted<HAdd>(
12355 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12356 value_index->ClearFlag(HValue::kCanOverflow);
12357 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
12358 }
12359 if_found.Else();
12360 {
12361 HIfContinuation did_add(graph()->CreateBasicBlock(),
12362 graph()->CreateBasicBlock());
12363 HValue* key_index = BuildOrderedHashTableAddEntry<OrderedHashMap>(
12364 table, key, hash, &did_add);
12365 IfBuilder if_did_add(this, &did_add);
12366 if_did_add.Then();
12367 {
12368 HValue* value_index = AddUncasted<HAdd>(
12369 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12370 value_index->ClearFlag(HValue::kCanOverflow);
12371 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
12372 }
12373 if_did_add.JoinContinuation(&return_or_call_runtime_continuation);
12374 }
12375 }
12376 }
12377 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12378
12379 {
12380 IfBuilder return_or_call_runtime(this,
12381 &return_or_call_runtime_continuation);
12382 return_or_call_runtime.Then();
12383 Push(receiver);
12384 return_or_call_runtime.Else();
12385 Add<HPushArguments>(receiver, key, value);
12386 Push(Add<HCallRuntime>(call->name(),
12387 Runtime::FunctionForId(Runtime::kMapSet), 3));
12388 }
12389
12390 return ast_context()->ReturnValue(Pop());
12391 } 12081 }
12392 12082
12393 12083
12394 void HOptimizedGraphBuilder::GenerateSetAdd(CallRuntime* call) { 12084 void HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) {
12395 DCHECK(call->arguments()->length() == 2); 12085 DCHECK(call->arguments()->length() == 0);
12396 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12086 return ast_context()->ReturnValue(graph()->GetConstantHole());
12397 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12398 HValue* key = Pop();
12399 HValue* receiver = Pop();
12400
12401 NoObservableSideEffectsScope no_effects(this);
12402
12403 HIfContinuation return_or_call_runtime_continuation(
12404 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12405 HIfContinuation got_string_hash;
12406 HValue* hash =
12407 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12408 IfBuilder string_checker(this, &got_string_hash);
12409 string_checker.Then();
12410 {
12411 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12412 HObjectAccess::ForJSCollectionTable());
12413 HValue* key_index =
12414 BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash);
12415 {
12416 IfBuilder if_not_found(this);
12417 if_not_found.If<HCompareNumericAndBranch>(
12418 key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ);
12419 if_not_found.Then();
12420 BuildOrderedHashTableAddEntry<OrderedHashSet>(
12421 table, key, hash, &return_or_call_runtime_continuation);
12422 }
12423 }
12424 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12425
12426 {
12427 IfBuilder return_or_call_runtime(this,
12428 &return_or_call_runtime_continuation);
12429 return_or_call_runtime.Then();
12430 Push(receiver);
12431 return_or_call_runtime.Else();
12432 Add<HPushArguments>(receiver, key);
12433 Push(Add<HCallRuntime>(call->name(),
12434 Runtime::FunctionForId(Runtime::kSetAdd), 2));
12435 }
12436
12437 return ast_context()->ReturnValue(Pop());
12438 } 12087 }
12439 12088
12440 12089
12441 template <typename CollectionType> 12090 void HOptimizedGraphBuilder::GenerateJSCollectionGetTable(CallRuntime* call) {
12442 void HOptimizedGraphBuilder::BuildJSCollectionDelete(
12443 CallRuntime* call, const Runtime::Function* c_function) {
12444 DCHECK(call->arguments()->length() == 2);
12445 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12446 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12447 HValue* key = Pop();
12448 HValue* receiver = Pop();
12449
12450 NoObservableSideEffectsScope no_effects(this);
12451
12452 HIfContinuation return_or_call_runtime_continuation(
12453 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12454 HIfContinuation got_string_hash;
12455 HValue* hash =
12456 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12457 IfBuilder string_checker(this, &got_string_hash);
12458 string_checker.Then();
12459 {
12460 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12461 HObjectAccess::ForJSCollectionTable());
12462 HValue* key_index =
12463 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
12464 {
12465 IfBuilder if_found(this);
12466 if_found.If<HCompareNumericAndBranch>(
12467 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
12468 if_found.Then();
12469 {
12470 // If we're removing an element, we might need to shrink.
12471 // If we do need to shrink, we'll be bailing out to the runtime.
12472 HValue* num_elements = Add<HLoadNamedField>(
12473 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfElements<
12474 CollectionType>());
12475 num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1());
12476 num_elements->ClearFlag(HValue::kCanOverflow);
12477
12478 HValue* num_buckets = Add<HLoadNamedField>(
12479 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfBuckets<
12480 CollectionType>());
12481 // threshold is capacity >> 2; we simplify this to num_buckets >> 1
12482 // since kLoadFactor is 2.
12483 STATIC_ASSERT(CollectionType::kLoadFactor == 2);
12484 HValue* threshold =
12485 AddUncasted<HShr>(num_buckets, graph()->GetConstant1());
12486
12487 IfBuilder if_need_not_shrink(this);
12488 if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold,
12489 Token::GTE);
12490 if_need_not_shrink.Then();
12491 {
12492 Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(),
12493 FAST_ELEMENTS);
12494
12495 // For maps, also need to clear the value.
12496 if (CollectionType::kChainOffset > 1) {
12497 HValue* value_index =
12498 AddUncasted<HAdd>(key_index, graph()->GetConstant1());
12499 value_index->ClearFlag(HValue::kCanOverflow);
12500 Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(),
12501 FAST_ELEMENTS);
12502 }
12503 STATIC_ASSERT(CollectionType::kChainOffset <= 2);
12504
12505 HValue* num_deleted = Add<HLoadNamedField>(
12506 table, nullptr,
12507 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12508 CollectionType>());
12509 num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1());
12510 num_deleted->ClearFlag(HValue::kCanOverflow);
12511 Add<HStoreNamedField>(
12512 table, HObjectAccess::ForOrderedHashTableNumberOfElements<
12513 CollectionType>(),
12514 num_elements);
12515 Add<HStoreNamedField>(
12516 table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12517 CollectionType>(),
12518 num_deleted);
12519 Push(graph()->GetConstantTrue());
12520 }
12521 if_need_not_shrink.JoinContinuation(
12522 &return_or_call_runtime_continuation);
12523 }
12524 if_found.Else();
12525 {
12526 // Not found, so we're done.
12527 Push(graph()->GetConstantFalse());
12528 }
12529 }
12530 }
12531 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12532
12533 {
12534 IfBuilder return_or_call_runtime(this,
12535 &return_or_call_runtime_continuation);
12536 return_or_call_runtime.Then();
12537 return_or_call_runtime.Else();
12538 Add<HPushArguments>(receiver, key);
12539 Push(Add<HCallRuntime>(call->name(), c_function, 2));
12540 }
12541
12542 return ast_context()->ReturnValue(Pop());
12543 }
12544
12545
12546 void HOptimizedGraphBuilder::GenerateMapDelete(CallRuntime* call) {
12547 BuildJSCollectionDelete<OrderedHashMap>(
12548 call, Runtime::FunctionForId(Runtime::kMapDelete));
12549 }
12550
12551
12552 void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) {
12553 BuildJSCollectionDelete<OrderedHashSet>(
12554 call, Runtime::FunctionForId(Runtime::kSetDelete));
12555 }
12556
12557
12558 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) {
12559 DCHECK(call->arguments()->length() == 1); 12091 DCHECK(call->arguments()->length() == 1);
12560 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12092 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12561 HValue* receiver = Pop(); 12093 HValue* receiver = Pop();
12562 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12563 HObjectAccess::ForJSCollectionTable());
12564 HInstruction* result = New<HLoadNamedField>( 12094 HInstruction* result = New<HLoadNamedField>(
12565 table, nullptr, 12095 receiver, nullptr, HObjectAccess::ForJSCollectionTable());
12566 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>());
12567 return ast_context()->ReturnInstruction(result, call->id()); 12096 return ast_context()->ReturnInstruction(result, call->id());
12568 } 12097 }
12569 12098
12570 12099
12571 void HOptimizedGraphBuilder::GenerateMapGetSize(CallRuntime* call) { 12100 void HOptimizedGraphBuilder::GenerateStringGetRawHashField(CallRuntime* call) {
12572 DCHECK(call->arguments()->length() == 1); 12101 DCHECK(call->arguments()->length() == 1);
12573 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12102 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12574 HValue* receiver = Pop(); 12103 HValue* object = Pop();
12575 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12576 HObjectAccess::ForJSCollectionTable());
12577 HInstruction* result = New<HLoadNamedField>( 12104 HInstruction* result = New<HLoadNamedField>(
12578 table, nullptr, 12105 object, nullptr, HObjectAccess::ForStringHashField());
12579 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashMap>());
12580 return ast_context()->ReturnInstruction(result, call->id()); 12106 return ast_context()->ReturnInstruction(result, call->id());
12581 } 12107 }
12582 12108
12583 12109
12584 template <typename CollectionType> 12110 template <typename CollectionType>
12585 HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() { 12111 HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() {
12586 static const int kCapacity = CollectionType::kMinCapacity; 12112 static const int kCapacity = CollectionType::kMinCapacity;
12587 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; 12113 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor;
12588 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + 12114 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex +
12589 kBucketCount + 12115 kBucketCount +
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
13411 if (ShouldProduceTraceOutput()) { 12937 if (ShouldProduceTraceOutput()) {
13412 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12938 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13413 } 12939 }
13414 12940
13415 #ifdef DEBUG 12941 #ifdef DEBUG
13416 graph_->Verify(false); // No full verify. 12942 graph_->Verify(false); // No full verify.
13417 #endif 12943 #endif
13418 } 12944 }
13419 12945
13420 } } // namespace v8::internal 12946 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698