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

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: Rename all the things, add more macros, and remove unnecessary %_CallFunctions Created 5 years, 9 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
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 12015 matching lines...) Expand 10 before | Expand all | Expand 10 after
12026 12026
12027 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 12027 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
12028 DCHECK(call->arguments()->length() == 1); 12028 DCHECK(call->arguments()->length() == 1);
12029 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12029 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12030 HValue* value = Pop(); 12030 HValue* value = Pop();
12031 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt); 12031 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt);
12032 return ast_context()->ReturnInstruction(result, call->id()); 12032 return ast_context()->ReturnInstruction(result, call->id());
12033 } 12033 }
12034 12034
12035 12035
12036 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToBucket( 12036 void HOptimizedGraphBuilder::GenerateFixedArrayGet(CallRuntime* call) {
12037 HValue* hash, HValue* num_buckets) { 12037 DCHECK(call->arguments()->length() == 2);
12038 HValue* mask = AddUncasted<HSub>(num_buckets, graph()->GetConstant1()); 12038 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12039 mask->ChangeRepresentation(Representation::Integer32()); 12039 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12040 mask->ClearFlag(HValue::kCanOverflow); 12040 HValue* index = Pop();
12041 return AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); 12041 HValue* object = Pop();
12042 HInstruction* result = New<HLoadKeyed>(object, index, nullptr, FAST_ELEMENTS);
Toon Verwaest 2015/03/30 12:55:42 Seems like it would be more honest to FAST_HOLEY_E
adamk 2015/03/30 18:44:54 Done.
arv (Not doing code reviews) 2015/03/30 18:55:22 Would that impact the performance?
adamk 2015/03/30 22:31:50 I don't believe so, but if it does, that's because
12043 return ast_context()->ReturnInstruction(result, call->id());
12042 } 12044 }
12043 12045
12044 12046
12045 template <typename CollectionType> 12047 void HOptimizedGraphBuilder::GenerateFixedArraySet(CallRuntime* call) {
12046 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToEntry(
12047 HValue* table, HValue* hash, HValue* num_buckets) {
12048 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets);
12049 HValue* entry_index = AddUncasted<HAdd>(
12050 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex));
12051 entry_index->ClearFlag(HValue::kCanOverflow);
12052 HValue* entry = Add<HLoadKeyed>(table, entry_index, nullptr, FAST_ELEMENTS);
12053 entry->set_type(HType::Smi());
12054 return entry;
12055 }
12056
12057
12058 template <typename CollectionType>
12059 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableEntryToIndex(
12060 HValue* entry, HValue* num_buckets) {
12061 HValue* index =
12062 AddUncasted<HMul>(entry, Add<HConstant>(CollectionType::kEntrySize));
12063 index->ClearFlag(HValue::kCanOverflow);
12064 index = AddUncasted<HAdd>(index, num_buckets);
12065 index->ClearFlag(HValue::kCanOverflow);
12066 index = AddUncasted<HAdd>(
12067 index, Add<HConstant>(CollectionType::kHashTableStartIndex));
12068 index->ClearFlag(HValue::kCanOverflow);
12069 return index;
12070 }
12071
12072
12073 template <typename CollectionType>
12074 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table,
12075 HValue* key,
12076 HValue* hash) {
12077 HValue* num_buckets = Add<HLoadNamedField>(
12078 table, nullptr,
12079 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
12080
12081 HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash,
12082 num_buckets);
12083
12084 Push(entry);
12085
12086 LoopBuilder loop(this);
12087 loop.BeginBody(1);
12088
12089 entry = Pop();
12090
12091 {
12092 IfBuilder if_not_found(this);
12093 if_not_found.If<HCompareNumericAndBranch>(
12094 entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ);
12095 if_not_found.Then();
12096 Push(entry);
12097 loop.Break();
12098 }
12099
12100 HValue* key_index =
12101 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
12102 HValue* candidate_key =
12103 Add<HLoadKeyed>(table, key_index, nullptr, FAST_ELEMENTS);
12104
12105 {
12106 IfBuilder if_keys_equal(this);
12107 if_keys_equal.If<HIsStringAndBranch>(candidate_key);
12108 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key,
12109 Token::EQ_STRICT);
12110 if_keys_equal.Then();
12111 Push(key_index);
12112 loop.Break();
12113 }
12114
12115 // BuildChainAt
12116 HValue* chain_index = AddUncasted<HAdd>(
12117 key_index, Add<HConstant>(CollectionType::kChainOffset));
12118 chain_index->ClearFlag(HValue::kCanOverflow);
12119 entry = Add<HLoadKeyed>(table, chain_index, nullptr, FAST_ELEMENTS);
12120 entry->set_type(HType::Smi());
12121 Push(entry);
12122
12123 loop.EndBody();
12124
12125 return Pop();
12126 }
12127
12128
12129 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) {
12130 DCHECK(call->arguments()->length() == 2);
12131 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12132 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12133 HValue* key = Pop();
12134 HValue* receiver = Pop();
12135
12136 NoObservableSideEffectsScope no_effects(this);
12137
12138 HIfContinuation continuation;
12139 HValue* hash =
12140 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation);
12141 {
12142 IfBuilder string_checker(this, &continuation);
12143 string_checker.Then();
12144 {
12145 HValue* table = Add<HLoadNamedField>(
12146 receiver, nullptr, HObjectAccess::ForJSCollectionTable());
12147 HValue* key_index =
12148 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
12149 IfBuilder if_found(this);
12150 if_found.If<HCompareNumericAndBranch>(
12151 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
12152 if_found.Then();
12153 {
12154 HValue* value_index = AddUncasted<HAdd>(
12155 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12156 value_index->ClearFlag(HValue::kCanOverflow);
12157 Push(Add<HLoadKeyed>(table, value_index, nullptr, FAST_ELEMENTS));
12158 }
12159 if_found.Else();
12160 Push(graph()->GetConstantUndefined());
12161 if_found.End();
12162 }
12163 string_checker.Else();
12164 {
12165 Add<HPushArguments>(receiver, key);
12166 Push(Add<HCallRuntime>(call->name(),
12167 Runtime::FunctionForId(Runtime::kMapGet), 2));
12168 }
12169 }
12170
12171 return ast_context()->ReturnValue(Pop());
12172 }
12173
12174
12175 HValue* HOptimizedGraphBuilder::BuildStringHashLoadIfIsStringAndHashComputed(
12176 HValue* object, HIfContinuation* continuation) {
12177 IfBuilder string_checker(this);
12178 string_checker.If<HIsStringAndBranch>(object);
12179 string_checker.And();
12180 HValue* hash = Add<HLoadNamedField>(object, nullptr,
12181 HObjectAccess::ForStringHashField());
12182 HValue* hash_not_computed_mask = Add<HConstant>(String::kHashNotComputedMask);
12183 HValue* hash_computed_test =
12184 AddUncasted<HBitwise>(Token::BIT_AND, hash, hash_not_computed_mask);
12185 string_checker.If<HCompareNumericAndBranch>(
12186 hash_computed_test, graph()->GetConstant0(), Token::EQ);
12187 string_checker.Then();
12188 HValue* shifted_hash =
12189 AddUncasted<HShr>(hash, Add<HConstant>(String::kHashShift));
12190 string_checker.CaptureContinuation(continuation);
12191 return shifted_hash;
12192 }
12193
12194
12195 template <typename CollectionType>
12196 void HOptimizedGraphBuilder::BuildJSCollectionHas(
12197 CallRuntime* call, const Runtime::Function* c_function) {
12198 DCHECK(call->arguments()->length() == 2);
12199 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12200 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12201 HValue* key = Pop();
12202 HValue* receiver = Pop();
12203
12204 NoObservableSideEffectsScope no_effects(this);
12205
12206 HIfContinuation continuation;
12207 HValue* hash =
12208 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation);
12209 {
12210 IfBuilder string_checker(this, &continuation);
12211 string_checker.Then();
12212 {
12213 HValue* table = Add<HLoadNamedField>(
12214 receiver, nullptr, HObjectAccess::ForJSCollectionTable());
12215 HValue* key_index =
12216 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
12217 {
12218 IfBuilder if_found(this);
12219 if_found.If<HCompareNumericAndBranch>(
12220 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
12221 if_found.Then();
12222 Push(graph()->GetConstantTrue());
12223 if_found.Else();
12224 Push(graph()->GetConstantFalse());
12225 }
12226 }
12227 string_checker.Else();
12228 {
12229 Add<HPushArguments>(receiver, key);
12230 Push(Add<HCallRuntime>(call->name(), c_function, 2));
12231 }
12232 }
12233
12234 return ast_context()->ReturnValue(Pop());
12235 }
12236
12237
12238 void HOptimizedGraphBuilder::GenerateMapHas(CallRuntime* call) {
12239 BuildJSCollectionHas<OrderedHashMap>(
12240 call, Runtime::FunctionForId(Runtime::kMapHas));
12241 }
12242
12243
12244 void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) {
12245 BuildJSCollectionHas<OrderedHashSet>(
12246 call, Runtime::FunctionForId(Runtime::kSetHas));
12247 }
12248
12249
12250 template <typename CollectionType>
12251 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableAddEntry(
12252 HValue* table, HValue* key, HValue* hash,
12253 HIfContinuation* join_continuation) {
12254 HValue* num_buckets = Add<HLoadNamedField>(
12255 table, nullptr,
12256 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
12257 HValue* capacity = AddUncasted<HMul>(
12258 num_buckets, Add<HConstant>(CollectionType::kLoadFactor));
12259 capacity->ClearFlag(HValue::kCanOverflow);
12260 HValue* num_elements = Add<HLoadNamedField>(
12261 table, nullptr,
12262 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>());
12263 HValue* num_deleted = Add<HLoadNamedField>(
12264 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12265 CollectionType>());
12266 HValue* used = AddUncasted<HAdd>(num_elements, num_deleted);
12267 used->ClearFlag(HValue::kCanOverflow);
12268 IfBuilder if_space_available(this);
12269 if_space_available.If<HCompareNumericAndBranch>(capacity, used, Token::GT);
12270 if_space_available.Then();
12271 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets);
12272 HValue* entry = used;
12273 HValue* key_index =
12274 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
12275
12276 HValue* bucket_index = AddUncasted<HAdd>(
12277 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex));
12278 bucket_index->ClearFlag(HValue::kCanOverflow);
12279 HValue* chain_entry =
12280 Add<HLoadKeyed>(table, bucket_index, nullptr, FAST_ELEMENTS);
12281 chain_entry->set_type(HType::Smi());
12282
12283 HValue* chain_index = AddUncasted<HAdd>(
12284 key_index, Add<HConstant>(CollectionType::kChainOffset));
12285 chain_index->ClearFlag(HValue::kCanOverflow);
12286
12287 Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS);
12288 Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS);
12289 Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS);
12290
12291 HValue* new_num_elements =
12292 AddUncasted<HAdd>(num_elements, graph()->GetConstant1());
12293 new_num_elements->ClearFlag(HValue::kCanOverflow);
12294 Add<HStoreNamedField>(
12295 table,
12296 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(),
12297 new_num_elements);
12298 if_space_available.JoinContinuation(join_continuation);
12299 return key_index;
12300 }
12301
12302
12303 void HOptimizedGraphBuilder::GenerateMapSet(CallRuntime* call) {
12304 DCHECK(call->arguments()->length() == 3); 12048 DCHECK(call->arguments()->length() == 3);
12305 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12049 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12306 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 12050 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12307 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 12051 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
12308 HValue* value = Pop(); 12052 HValue* value = Pop();
12309 HValue* key = Pop(); 12053 HValue* index = Pop();
12310 HValue* receiver = Pop(); 12054 HValue* object = Pop();
12311
12312 NoObservableSideEffectsScope no_effects(this); 12055 NoObservableSideEffectsScope no_effects(this);
12313 12056 Add<HStoreKeyed>(object, index, value, FAST_ELEMENTS);
Toon Verwaest 2015/03/30 12:55:42 FAST_HOLEY_ELEMENTS?
adamk 2015/03/30 18:44:54 Done.
12314 HIfContinuation return_or_call_runtime_continuation( 12057 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
12315 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12316 HIfContinuation got_string_hash;
12317 HValue* hash =
12318 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12319 IfBuilder string_checker(this, &got_string_hash);
12320 string_checker.Then();
12321 {
12322 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12323 HObjectAccess::ForJSCollectionTable());
12324 HValue* key_index =
12325 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
12326 {
12327 IfBuilder if_found(this);
12328 if_found.If<HCompareNumericAndBranch>(
12329 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
12330 if_found.Then();
12331 {
12332 HValue* value_index = AddUncasted<HAdd>(
12333 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12334 value_index->ClearFlag(HValue::kCanOverflow);
12335 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
12336 }
12337 if_found.Else();
12338 {
12339 HIfContinuation did_add(graph()->CreateBasicBlock(),
12340 graph()->CreateBasicBlock());
12341 HValue* key_index = BuildOrderedHashTableAddEntry<OrderedHashMap>(
12342 table, key, hash, &did_add);
12343 IfBuilder if_did_add(this, &did_add);
12344 if_did_add.Then();
12345 {
12346 HValue* value_index = AddUncasted<HAdd>(
12347 key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
12348 value_index->ClearFlag(HValue::kCanOverflow);
12349 Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
12350 }
12351 if_did_add.JoinContinuation(&return_or_call_runtime_continuation);
12352 }
12353 }
12354 }
12355 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12356
12357 {
12358 IfBuilder return_or_call_runtime(this,
12359 &return_or_call_runtime_continuation);
12360 return_or_call_runtime.Then();
12361 Push(receiver);
12362 return_or_call_runtime.Else();
12363 Add<HPushArguments>(receiver, key, value);
12364 Push(Add<HCallRuntime>(call->name(),
12365 Runtime::FunctionForId(Runtime::kMapSet), 3));
12366 }
12367
12368 return ast_context()->ReturnValue(Pop());
12369 } 12058 }
12370 12059
12371 12060
12372 void HOptimizedGraphBuilder::GenerateSetAdd(CallRuntime* call) { 12061 void HOptimizedGraphBuilder::GenerateTheHole(CallRuntime* call) {
12373 DCHECK(call->arguments()->length() == 2); 12062 DCHECK(call->arguments()->length() == 0);
12374 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12063 return ast_context()->ReturnValue(graph()->GetConstantHole());
12375 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12376 HValue* key = Pop();
12377 HValue* receiver = Pop();
12378
12379 NoObservableSideEffectsScope no_effects(this);
12380
12381 HIfContinuation return_or_call_runtime_continuation(
12382 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12383 HIfContinuation got_string_hash;
12384 HValue* hash =
12385 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12386 IfBuilder string_checker(this, &got_string_hash);
12387 string_checker.Then();
12388 {
12389 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12390 HObjectAccess::ForJSCollectionTable());
12391 HValue* key_index =
12392 BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash);
12393 {
12394 IfBuilder if_not_found(this);
12395 if_not_found.If<HCompareNumericAndBranch>(
12396 key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ);
12397 if_not_found.Then();
12398 BuildOrderedHashTableAddEntry<OrderedHashSet>(
12399 table, key, hash, &return_or_call_runtime_continuation);
12400 }
12401 }
12402 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12403
12404 {
12405 IfBuilder return_or_call_runtime(this,
12406 &return_or_call_runtime_continuation);
12407 return_or_call_runtime.Then();
12408 Push(receiver);
12409 return_or_call_runtime.Else();
12410 Add<HPushArguments>(receiver, key);
12411 Push(Add<HCallRuntime>(call->name(),
12412 Runtime::FunctionForId(Runtime::kSetAdd), 2));
12413 }
12414
12415 return ast_context()->ReturnValue(Pop());
12416 } 12064 }
12417 12065
12418 12066
12419 template <typename CollectionType> 12067 void HOptimizedGraphBuilder::GenerateJSCollectionGetTable(CallRuntime* call) {
12420 void HOptimizedGraphBuilder::BuildJSCollectionDelete(
12421 CallRuntime* call, const Runtime::Function* c_function) {
12422 DCHECK(call->arguments()->length() == 2);
12423 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12424 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12425 HValue* key = Pop();
12426 HValue* receiver = Pop();
12427
12428 NoObservableSideEffectsScope no_effects(this);
12429
12430 HIfContinuation return_or_call_runtime_continuation(
12431 graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
12432 HIfContinuation got_string_hash;
12433 HValue* hash =
12434 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
12435 IfBuilder string_checker(this, &got_string_hash);
12436 string_checker.Then();
12437 {
12438 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12439 HObjectAccess::ForJSCollectionTable());
12440 HValue* key_index =
12441 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
12442 {
12443 IfBuilder if_found(this);
12444 if_found.If<HCompareNumericAndBranch>(
12445 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
12446 if_found.Then();
12447 {
12448 // If we're removing an element, we might need to shrink.
12449 // If we do need to shrink, we'll be bailing out to the runtime.
12450 HValue* num_elements = Add<HLoadNamedField>(
12451 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfElements<
12452 CollectionType>());
12453 num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1());
12454 num_elements->ClearFlag(HValue::kCanOverflow);
12455
12456 HValue* num_buckets = Add<HLoadNamedField>(
12457 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfBuckets<
12458 CollectionType>());
12459 // threshold is capacity >> 2; we simplify this to num_buckets >> 1
12460 // since kLoadFactor is 2.
12461 STATIC_ASSERT(CollectionType::kLoadFactor == 2);
12462 HValue* threshold =
12463 AddUncasted<HShr>(num_buckets, graph()->GetConstant1());
12464
12465 IfBuilder if_need_not_shrink(this);
12466 if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold,
12467 Token::GTE);
12468 if_need_not_shrink.Then();
12469 {
12470 Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(),
12471 FAST_ELEMENTS);
12472
12473 // For maps, also need to clear the value.
12474 if (CollectionType::kChainOffset > 1) {
12475 HValue* value_index =
12476 AddUncasted<HAdd>(key_index, graph()->GetConstant1());
12477 value_index->ClearFlag(HValue::kCanOverflow);
12478 Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(),
12479 FAST_ELEMENTS);
12480 }
12481 STATIC_ASSERT(CollectionType::kChainOffset <= 2);
12482
12483 HValue* num_deleted = Add<HLoadNamedField>(
12484 table, nullptr,
12485 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12486 CollectionType>());
12487 num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1());
12488 num_deleted->ClearFlag(HValue::kCanOverflow);
12489 Add<HStoreNamedField>(
12490 table, HObjectAccess::ForOrderedHashTableNumberOfElements<
12491 CollectionType>(),
12492 num_elements);
12493 Add<HStoreNamedField>(
12494 table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
12495 CollectionType>(),
12496 num_deleted);
12497 Push(graph()->GetConstantTrue());
12498 }
12499 if_need_not_shrink.JoinContinuation(
12500 &return_or_call_runtime_continuation);
12501 }
12502 if_found.Else();
12503 {
12504 // Not found, so we're done.
12505 Push(graph()->GetConstantFalse());
12506 }
12507 }
12508 }
12509 string_checker.JoinContinuation(&return_or_call_runtime_continuation);
12510
12511 {
12512 IfBuilder return_or_call_runtime(this,
12513 &return_or_call_runtime_continuation);
12514 return_or_call_runtime.Then();
12515 return_or_call_runtime.Else();
12516 Add<HPushArguments>(receiver, key);
12517 Push(Add<HCallRuntime>(call->name(), c_function, 2));
12518 }
12519
12520 return ast_context()->ReturnValue(Pop());
12521 }
12522
12523
12524 void HOptimizedGraphBuilder::GenerateMapDelete(CallRuntime* call) {
12525 BuildJSCollectionDelete<OrderedHashMap>(
12526 call, Runtime::FunctionForId(Runtime::kMapDelete));
12527 }
12528
12529
12530 void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) {
12531 BuildJSCollectionDelete<OrderedHashSet>(
12532 call, Runtime::FunctionForId(Runtime::kSetDelete));
12533 }
12534
12535
12536 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) {
12537 DCHECK(call->arguments()->length() == 1); 12068 DCHECK(call->arguments()->length() == 1);
12538 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12069 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12539 HValue* receiver = Pop(); 12070 HValue* receiver = Pop();
12540 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12541 HObjectAccess::ForJSCollectionTable());
12542 HInstruction* result = New<HLoadNamedField>( 12071 HInstruction* result = New<HLoadNamedField>(
12543 table, nullptr, 12072 receiver, nullptr, HObjectAccess::ForJSCollectionTable());
12544 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>());
12545 return ast_context()->ReturnInstruction(result, call->id()); 12073 return ast_context()->ReturnInstruction(result, call->id());
12546 } 12074 }
12547 12075
12548 12076
12549 void HOptimizedGraphBuilder::GenerateMapGetSize(CallRuntime* call) { 12077 void HOptimizedGraphBuilder::GenerateStringGetRawHashField(CallRuntime* call) {
12550 DCHECK(call->arguments()->length() == 1); 12078 DCHECK(call->arguments()->length() == 1);
12551 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12079 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12552 HValue* receiver = Pop(); 12080 HValue* object = Pop();
12553 HValue* table = Add<HLoadNamedField>(receiver, nullptr,
12554 HObjectAccess::ForJSCollectionTable());
12555 HInstruction* result = New<HLoadNamedField>( 12081 HInstruction* result = New<HLoadNamedField>(
12556 table, nullptr, 12082 object, nullptr, HObjectAccess::ForStringHashField());
12557 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashMap>());
12558 return ast_context()->ReturnInstruction(result, call->id()); 12083 return ast_context()->ReturnInstruction(result, call->id());
12559 } 12084 }
12560 12085
12561 12086
12562 template <typename CollectionType> 12087 template <typename CollectionType>
12563 HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() { 12088 HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() {
12564 static const int kCapacity = CollectionType::kMinCapacity; 12089 static const int kCapacity = CollectionType::kMinCapacity;
12565 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; 12090 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor;
12566 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + 12091 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex +
12567 kBucketCount + 12092 kBucketCount +
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after
13390 if (ShouldProduceTraceOutput()) { 12915 if (ShouldProduceTraceOutput()) {
13391 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12916 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13392 } 12917 }
13393 12918
13394 #ifdef DEBUG 12919 #ifdef DEBUG
13395 graph_->Verify(false); // No full verify. 12920 graph_->Verify(false); // No full verify.
13396 #endif 12921 #endif
13397 } 12922 }
13398 12923
13399 } } // namespace v8::internal 12924 } } // namespace v8::internal
OLDNEW
« src/harmony-templates.js ('K') | « 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