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

Side by Side Diff: src/hydrogen.cc

Issue 142693005: A64: Synchronize with r16918. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 644
645 HConstant* HGraph::GetConstantMinus1() { 645 HConstant* HGraph::GetConstantMinus1() {
646 return GetConstant(&constant_minus1_, -1); 646 return GetConstant(&constant_minus1_, -1);
647 } 647 }
648 648
649 649
650 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \ 650 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \
651 HConstant* HGraph::GetConstant##Name() { \ 651 HConstant* HGraph::GetConstant##Name() { \
652 if (!constant_##name##_.is_set()) { \ 652 if (!constant_##name##_.is_set()) { \
653 HConstant* constant = new(zone()) HConstant( \ 653 HConstant* constant = new(zone()) HConstant( \
654 isolate()->factory()->name##_value(), \ 654 Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
655 UniqueValueId::name##_value(isolate()->heap()), \
656 Representation::Tagged(), \ 655 Representation::Tagged(), \
657 htype, \ 656 htype, \
658 false, \ 657 false, \
659 true, \ 658 true, \
660 false, \ 659 false, \
661 boolean_value); \ 660 boolean_value); \
662 constant->InsertAfter(GetConstantUndefined()); \ 661 constant->InsertAfter(GetConstantUndefined()); \
663 constant_##name##_.set(constant); \ 662 constant_##name##_.set(constant); \
664 } \ 663 } \
665 return constant_##name##_.get(); \ 664 return constant_##name##_.get(); \
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 : last_true_block_; 800 : last_true_block_;
802 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL) 801 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL)
803 ? builder_->current_block() 802 ? builder_->current_block()
804 : first_false_block_; 803 : first_false_block_;
805 continuation->Capture(true_block, false_block, position_); 804 continuation->Capture(true_block, false_block, position_);
806 captured_ = true; 805 captured_ = true;
807 End(); 806 End();
808 } 807 }
809 808
810 809
810 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
811 ASSERT(!finished_);
812 ASSERT(!captured_);
813 HBasicBlock* true_block = last_true_block_ == NULL
814 ? first_true_block_
815 : last_true_block_;
816 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL)
817 ? builder_->current_block()
818 : first_false_block_;
819 if (true_block != NULL && !true_block->IsFinished()) {
820 ASSERT(continuation->IsTrueReachable());
821 true_block->GotoNoSimulate(continuation->true_branch());
822 }
823 if (false_block != NULL && !false_block->IsFinished()) {
824 ASSERT(continuation->IsFalseReachable());
825 false_block->GotoNoSimulate(continuation->false_branch());
826 }
827 captured_ = true;
828 End();
829 }
830
831
811 void HGraphBuilder::IfBuilder::Then() { 832 void HGraphBuilder::IfBuilder::Then() {
812 ASSERT(!captured_); 833 ASSERT(!captured_);
813 ASSERT(!finished_); 834 ASSERT(!finished_);
814 did_then_ = true; 835 did_then_ = true;
815 if (needs_compare_) { 836 if (needs_compare_) {
816 // Handle if's without any expressions, they jump directly to the "else" 837 // Handle if's without any expressions, they jump directly to the "else"
817 // branch. However, we must pretend that the "then" branch is reachable, 838 // branch. However, we must pretend that the "then" branch is reachable,
818 // so that the graph builder visits it and sees any live range extending 839 // so that the graph builder visits it and sees any live range extending
819 // constructs within it. 840 // constructs within it.
820 HConstant* constant_false = builder_->graph()->GetConstantFalse(); 841 HConstant* constant_false = builder_->graph()->GetConstantFalse();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 finished_ = true; 1033 finished_ = true;
1013 } 1034 }
1014 1035
1015 1036
1016 HGraph* HGraphBuilder::CreateGraph() { 1037 HGraph* HGraphBuilder::CreateGraph() {
1017 graph_ = new(zone()) HGraph(info_); 1038 graph_ = new(zone()) HGraph(info_);
1018 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 1039 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
1019 CompilationPhase phase("H_Block building", info_); 1040 CompilationPhase phase("H_Block building", info_);
1020 set_current_block(graph()->entry_block()); 1041 set_current_block(graph()->entry_block());
1021 if (!BuildGraph()) return NULL; 1042 if (!BuildGraph()) return NULL;
1022 graph()->FinalizeUniqueValueIds(); 1043 graph()->FinalizeUniqueness();
1023 return graph_; 1044 return graph_;
1024 } 1045 }
1025 1046
1026 1047
1027 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1048 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
1028 ASSERT(current_block() != NULL); 1049 ASSERT(current_block() != NULL);
1029 current_block()->AddInstruction(instr); 1050 current_block()->AddInstruction(instr);
1030 if (graph()->IsInsideNoSideEffectsScope()) { 1051 if (graph()->IsInsideNoSideEffectsScope()) {
1031 instr->SetFlag(HValue::kHasNoObservableSideEffects); 1052 instr->SetFlag(HValue::kHasNoObservableSideEffects);
1032 } 1053 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1267 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1247 array_length, elements_length); 1268 array_length, elements_length);
1248 1269
1249 if_builder.End(); 1270 if_builder.End();
1250 } 1271 }
1251 1272
1252 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); 1273 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1253 } 1274 }
1254 1275
1255 1276
1277 HValue* HGraphBuilder::BuildLookupNumberStringCache(
1278 HValue* object,
1279 HIfContinuation* continuation) {
1280 // Create a joinable continuation.
1281 HIfContinuation found(graph()->CreateBasicBlock(),
1282 graph()->CreateBasicBlock());
1283
1284 // Load the number string cache.
1285 HValue* number_string_cache =
1286 Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
1287
1288 // Make the hash maks from the length of the number string cache. It
1289 // contains two elements (number and string) for each cache entry.
1290 HValue* mask = AddLoadFixedArrayLength(number_string_cache);
1291 mask->set_type(HType::Smi());
1292 mask = Add<HSar>(mask, graph()->GetConstant1());
1293 mask = Add<HSub>(mask, graph()->GetConstant1());
1294
1295 // Check whether object is a smi.
1296 IfBuilder if_objectissmi(this);
1297 if_objectissmi.If<HIsSmiAndBranch>(object);
1298 if_objectissmi.Then();
1299 {
1300 // Compute hash for smi similar to smi_get_hash().
1301 HValue* hash = Add<HBitwise>(Token::BIT_AND, object, mask);
1302
1303 // Load the key.
1304 HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
1305 HValue* key = AddFastElementAccess(number_string_cache, key_index,
1306 NULL, NULL, FAST_ELEMENTS, false,
1307 ALLOW_RETURN_HOLE, STANDARD_STORE);
1308
1309 // Check if object == key.
1310 IfBuilder if_objectiskey(this);
1311 if_objectiskey.If<HCompareObjectEqAndBranch>(key, object);
1312 if_objectiskey.Then();
1313 {
1314 // Make the key_index available.
1315 Push(key_index);
1316 }
1317 if_objectiskey.JoinContinuation(&found);
1318 }
1319 if_objectissmi.Else();
1320 {
1321 // Check if object is a heap number.
1322 IfBuilder if_objectisnumber(this);
1323 if_objectisnumber.If<HCompareMap>(
1324 object, isolate()->factory()->heap_number_map());
1325 if_objectisnumber.Then();
1326 {
1327 // Compute hash for heap number similar to double_get_hash().
1328 HValue* low = Add<HLoadNamedField>(
1329 object, HObjectAccess::ForHeapNumberValueLowestBits());
1330 HValue* high = Add<HLoadNamedField>(
1331 object, HObjectAccess::ForHeapNumberValueHighestBits());
1332 HValue* hash = Add<HBitwise>(Token::BIT_XOR, low, high);
1333 hash = Add<HBitwise>(Token::BIT_AND, hash, mask);
1334
1335 // Load the key.
1336 HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
1337 HValue* key = AddFastElementAccess(number_string_cache, key_index,
1338 NULL, NULL, FAST_ELEMENTS, false,
1339 ALLOW_RETURN_HOLE, STANDARD_STORE);
1340
1341 // Check if key is a heap number.
1342 IfBuilder if_keyisnumber(this);
1343 if_keyisnumber.IfNot<HIsSmiAndBranch>(key);
1344 if_keyisnumber.AndIf<HCompareMap>(
1345 key, isolate()->factory()->heap_number_map());
1346 if_keyisnumber.Then();
1347 {
1348 // Check if values of key and object match.
1349 IfBuilder if_keyeqobject(this);
1350 if_keyeqobject.If<HCompareNumericAndBranch>(
1351 Add<HLoadNamedField>(key, HObjectAccess::ForHeapNumberValue()),
1352 Add<HLoadNamedField>(object, HObjectAccess::ForHeapNumberValue()),
1353 Token::EQ);
1354 if_keyeqobject.Then();
1355 {
1356 // Make the key_index available.
1357 Push(key_index);
1358 }
1359 if_keyeqobject.JoinContinuation(&found);
1360 }
1361 if_keyisnumber.JoinContinuation(&found);
1362 }
1363 if_objectisnumber.JoinContinuation(&found);
1364 }
1365 if_objectissmi.End();
1366
1367 // Check for cache hit.
1368 IfBuilder if_found(this, &found);
1369 if_found.Then();
1370
1371 // Load the value in case of cache hit.
1372 HValue* key_index = Pop();
1373 HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1());
1374 HValue* value = AddFastElementAccess(number_string_cache, value_index,
1375 NULL, NULL, FAST_ELEMENTS, false,
1376 ALLOW_RETURN_HOLE, STANDARD_STORE);
1377 AddIncrementCounter(isolate()->counters()->number_to_string_native());
1378
1379 if_found.CaptureContinuation(continuation);
1380
1381 // The value is only available in true branch of continuation.
1382 return value;
1383 }
1384
1385
1386 HValue* HGraphBuilder::BuildNumberToString(HValue* number) {
1387 NoObservableSideEffectsScope scope(this);
1388
1389 // Lookup the number in the number string cache.
1390 HIfContinuation continuation;
1391 HValue* value = BuildLookupNumberStringCache(number, &continuation);
1392 IfBuilder if_found(this, &continuation);
1393 if_found.Then();
1394
1395 // Cache hit.
1396 Push(value);
1397
1398 if_found.Else();
1399
1400 // Cache miss, fallback to runtime.
1401 Add<HPushArgument>(number);
1402 Push(Add<HCallRuntime>(
1403 isolate()->factory()->empty_string(),
1404 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1405 1));
1406
1407 if_found.End();
1408
1409 return Pop();
1410 }
1411
1412
1256 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1413 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1257 HValue* checked_object, 1414 HValue* checked_object,
1258 HValue* key, 1415 HValue* key,
1259 HValue* val, 1416 HValue* val,
1260 bool is_js_array, 1417 bool is_js_array,
1261 ElementsKind elements_kind, 1418 ElementsKind elements_kind,
1262 bool is_store, 1419 bool is_store,
1263 LoadKeyedHoleMode load_mode, 1420 LoadKeyedHoleMode load_mode,
1264 KeyedAccessStoreMode store_mode) { 1421 KeyedAccessStoreMode store_mode) {
1265 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 1422 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array);
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 if_nil.CaptureContinuation(continuation); 1978 if_nil.CaptureContinuation(continuation);
1822 } 1979 }
1823 1980
1824 1981
1825 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object, 1982 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
1826 int previous_object_size, 1983 int previous_object_size,
1827 HValue* alloc_site) { 1984 HValue* alloc_site) {
1828 ASSERT(alloc_site != NULL); 1985 ASSERT(alloc_site != NULL);
1829 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>( 1986 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
1830 previous_object, previous_object_size); 1987 previous_object, previous_object_size);
1831 Handle<Map> alloc_memento_map( 1988 Handle<Map> alloc_memento_map =
1832 isolate()->heap()->allocation_memento_map()); 1989 isolate()->factory()->allocation_memento_map();
1833 AddStoreMapConstant(alloc_memento, alloc_memento_map); 1990 AddStoreMapConstant(alloc_memento, alloc_memento_map);
1834 HObjectAccess access = HObjectAccess::ForAllocationMementoSite(); 1991 HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
1835 Add<HStoreNamedField>(alloc_memento, access, alloc_site); 1992 Add<HStoreNamedField>(alloc_memento, access, alloc_site);
1836 return alloc_memento; 1993 return alloc_memento;
1837 } 1994 }
1838 1995
1839 1996
1840 HInstruction* HGraphBuilder::BuildGetNativeContext() { 1997 HInstruction* HGraphBuilder::BuildGetNativeContext() {
1841 // Get the global context, then the native context 1998 // Get the global context, then the native context
1842 HInstruction* global_object = Add<HGlobalObject>(); 1999 HInstruction* global_object = Add<HGlobalObject>();
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 } 2287 }
2131 2288
2132 2289
2133 HBasicBlock* HGraph::CreateBasicBlock() { 2290 HBasicBlock* HGraph::CreateBasicBlock() {
2134 HBasicBlock* result = new(zone()) HBasicBlock(this); 2291 HBasicBlock* result = new(zone()) HBasicBlock(this);
2135 blocks_.Add(result, zone()); 2292 blocks_.Add(result, zone());
2136 return result; 2293 return result;
2137 } 2294 }
2138 2295
2139 2296
2140 void HGraph::FinalizeUniqueValueIds() { 2297 void HGraph::FinalizeUniqueness() {
2141 DisallowHeapAllocation no_gc; 2298 DisallowHeapAllocation no_gc;
2142 ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread()); 2299 ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
2143 for (int i = 0; i < blocks()->length(); ++i) { 2300 for (int i = 0; i < blocks()->length(); ++i) {
2144 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { 2301 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
2145 it.Current()->FinalizeUniqueValueId(); 2302 it.Current()->FinalizeUniqueness();
2146 } 2303 }
2147 } 2304 }
2148 } 2305 }
2149 2306
2150 2307
2151 // Block ordering was implemented with two mutually recursive methods, 2308 // Block ordering was implemented with two mutually recursive methods,
2152 // HGraph::Postorder and HGraph::PostorderLoopBlocks. 2309 // HGraph::Postorder and HGraph::PostorderLoopBlocks.
2153 // The recursion could lead to stack overflow so the algorithm has been 2310 // The recursion could lead to stack overflow so the algorithm has been
2154 // implemented iteratively. 2311 // implemented iteratively.
2155 // At a high level the algorithm looks like this: 2312 // At a high level the algorithm looks like this:
(...skipping 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after
4079 4236
4080 4237
4081 // Determines whether the given array or object literal boilerplate satisfies 4238 // Determines whether the given array or object literal boilerplate satisfies
4082 // all limits to be considered for fast deep-copying and computes the total 4239 // all limits to be considered for fast deep-copying and computes the total
4083 // size of all objects that are part of the graph. 4240 // size of all objects that are part of the graph.
4084 static bool IsFastLiteral(Handle<JSObject> boilerplate, 4241 static bool IsFastLiteral(Handle<JSObject> boilerplate,
4085 int max_depth, 4242 int max_depth,
4086 int* max_properties) { 4243 int* max_properties) {
4087 if (boilerplate->map()->is_deprecated()) { 4244 if (boilerplate->map()->is_deprecated()) {
4088 Handle<Object> result = JSObject::TryMigrateInstance(boilerplate); 4245 Handle<Object> result = JSObject::TryMigrateInstance(boilerplate);
4089 if (result->IsSmi()) return false; 4246 if (result.is_null()) return false;
4090 } 4247 }
4091 4248
4092 ASSERT(max_depth >= 0 && *max_properties >= 0); 4249 ASSERT(max_depth >= 0 && *max_properties >= 0);
4093 if (max_depth == 0) return false; 4250 if (max_depth == 0) return false;
4094 4251
4095 Isolate* isolate = boilerplate->GetIsolate(); 4252 Isolate* isolate = boilerplate->GetIsolate();
4096 Handle<FixedArrayBase> elements(boilerplate->elements()); 4253 Handle<FixedArrayBase> elements(boilerplate->elements());
4097 if (elements->length() > 0 && 4254 if (elements->length() > 0 &&
4098 elements->map() != isolate->heap()->fixed_cow_array_map()) { 4255 elements->map() != isolate->heap()->fixed_cow_array_map()) {
4099 if (boilerplate->HasFastObjectElements()) { 4256 if (boilerplate->HasFastObjectElements()) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
4292 } 4449 }
4293 4450
4294 ASSERT(!raw_boilerplate.is_null()); 4451 ASSERT(!raw_boilerplate.is_null());
4295 ASSERT(site->IsLiteralSite()); 4452 ASSERT(site->IsLiteralSite());
4296 4453
4297 Handle<JSObject> boilerplate_object = 4454 Handle<JSObject> boilerplate_object =
4298 Handle<JSObject>::cast(raw_boilerplate); 4455 Handle<JSObject>::cast(raw_boilerplate);
4299 ElementsKind boilerplate_elements_kind = 4456 ElementsKind boilerplate_elements_kind =
4300 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); 4457 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind();
4301 4458
4302 // TODO(mvstanton): This heuristic is only a temporary solution. In the 4459 ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type()));
4303 // end, we want to quit creating allocation site info after a certain number
4304 // of GCs for a call site.
4305 AllocationSiteMode mode = AllocationSite::GetMode(
4306 boilerplate_elements_kind);
4307 4460
4308 // Check whether to use fast or slow deep-copying for boilerplate. 4461 // Check whether to use fast or slow deep-copying for boilerplate.
4309 int max_properties = kMaxFastLiteralProperties; 4462 int max_properties = kMaxFastLiteralProperties;
4310 if (IsFastLiteral(boilerplate_object, 4463 if (IsFastLiteral(boilerplate_object,
4311 kMaxFastLiteralDepth, 4464 kMaxFastLiteralDepth,
4312 &max_properties)) { 4465 &max_properties)) {
4466 // TODO(mvstanton): This heuristic is only a temporary solution. In the
4467 // end, we want to quit creating allocation site info after a certain number
4468 // of GCs for a call site.
4469 AllocationSiteMode mode = AllocationSite::GetMode(
4470 boilerplate_elements_kind);
4471
4472 // it doesn't make sense to create allocation mementos if we are going to
4473 // create in old space.
4474 if (mode == TRACK_ALLOCATION_SITE &&
4475 isolate()->heap()->GetPretenureMode() == TENURED) {
4476 mode = DONT_TRACK_ALLOCATION_SITE;
4477 }
4478
4313 literal = BuildFastLiteral(boilerplate_object, 4479 literal = BuildFastLiteral(boilerplate_object,
4314 site, 4480 site,
4315 mode); 4481 mode);
4316 } else { 4482 } else {
4317 NoObservableSideEffectsScope no_effects(this); 4483 NoObservableSideEffectsScope no_effects(this);
4318 // Boilerplate already exists and constant elements are never accessed, 4484 // Boilerplate already exists and constant elements are never accessed,
4319 // pass an empty fixed array to the runtime function instead. 4485 // pass an empty fixed array to the runtime function instead.
4320 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 4486 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
4321 int literal_index = expr->literal_index(); 4487 int literal_index = expr->literal_index();
4322 4488
(...skipping 1794 matching lines...) Expand 10 before | Expand all | Expand 10 after
6117 set_current_block(if_false); 6283 set_current_block(if_false);
6118 } 6284 }
6119 6285
6120 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6286 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6121 // know about and do not want to handle ones we've never seen. Otherwise 6287 // know about and do not want to handle ones we've never seen. Otherwise
6122 // use a generic IC. 6288 // use a generic IC.
6123 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6289 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6124 // Because the deopt may be the only path in the polymorphic call, make sure 6290 // Because the deopt may be the only path in the polymorphic call, make sure
6125 // that the environment stack matches the depth on deopt that it otherwise 6291 // that the environment stack matches the depth on deopt that it otherwise
6126 // would have had after a successful call. 6292 // would have had after a successful call.
6127 Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1)); 6293 Drop(argument_count);
6294 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
6128 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); 6295 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join);
6129 } else { 6296 } else {
6130 HValue* context = environment()->context(); 6297 HValue* context = environment()->context();
6131 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); 6298 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
6132 call->set_position(expr->position()); 6299 call->set_position(expr->position());
6133 PreProcessCall(call); 6300 PreProcessCall(call);
6134 6301
6135 if (join != NULL) { 6302 if (join != NULL) {
6136 AddInstruction(call); 6303 AddInstruction(call);
6137 if (!ast_context()->IsEffect()) Push(call); 6304 if (!ast_context()->IsEffect()) Push(call);
(...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after
7639 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { 7806 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
7640 if (value->IsConstant()) { 7807 if (value->IsConstant()) {
7641 HConstant* constant = HConstant::cast(value); 7808 HConstant* constant = HConstant::cast(value);
7642 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); 7809 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
7643 if (number.has_value) { 7810 if (number.has_value) {
7644 *expected = handle(Type::Number(), isolate()); 7811 *expected = handle(Type::Number(), isolate());
7645 return AddInstruction(number.value); 7812 return AddInstruction(number.value);
7646 } 7813 }
7647 } 7814 }
7648 7815
7816 // We put temporary values on the stack, which don't correspond to anything
7817 // in baseline code. Since nothing is observable we avoid recording those
7818 // pushes with a NoObservableSideEffectsScope.
7819 NoObservableSideEffectsScope no_effects(this);
7820
7649 Handle<Type> expected_type = *expected; 7821 Handle<Type> expected_type = *expected;
7650 7822
7651 // Separate the number type from the rest. 7823 // Separate the number type from the rest.
7652 Handle<Type> expected_obj = handle(Type::Intersect( 7824 Handle<Type> expected_obj = handle(Type::Intersect(
7653 expected_type, handle(Type::NonNumber(), isolate())), isolate()); 7825 expected_type, handle(Type::NonNumber(), isolate())), isolate());
7654 Handle<Type> expected_number = handle(Type::Intersect( 7826 Handle<Type> expected_number = handle(Type::Intersect(
7655 expected_type, handle(Type::Number(), isolate())), isolate()); 7827 expected_type, handle(Type::Number(), isolate())), isolate());
7656 7828
7657 // We expect to get a number. 7829 // We expect to get a number.
7658 // (We need to check first, since Type::None->Is(Type::Any()) == true. 7830 // (We need to check first, since Type::None->Is(Type::Any()) == true.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
7704 } 7876 }
7705 7877
7706 return value; 7878 return value;
7707 } 7879 }
7708 7880
7709 7881
7710 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 7882 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
7711 BinaryOperation* expr, 7883 BinaryOperation* expr,
7712 HValue* left, 7884 HValue* left,
7713 HValue* right) { 7885 HValue* right) {
7714 HValue* context = environment()->context();
7715 Handle<Type> left_type = expr->left()->bounds().lower; 7886 Handle<Type> left_type = expr->left()->bounds().lower;
7716 Handle<Type> right_type = expr->right()->bounds().lower; 7887 Handle<Type> right_type = expr->right()->bounds().lower;
7717 Handle<Type> result_type = expr->bounds().lower; 7888 Handle<Type> result_type = expr->bounds().lower;
7718 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 7889 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
7719 7890
7720 return HGraphBuilder::BuildBinaryOperation(expr->op(), left, right, 7891 return HGraphBuilder::BuildBinaryOperation(expr->op(), left, right,
7721 left_type, right_type, result_type, fixed_right_arg, context); 7892 left_type, right_type, result_type, fixed_right_arg);
7722 } 7893 }
7723 7894
7724 7895
7725 HInstruction* HGraphBuilder::BuildBinaryOperation( 7896 HInstruction* HGraphBuilder::BuildBinaryOperation(
7726 Token::Value op, 7897 Token::Value op,
7727 HValue* left, 7898 HValue* left,
7728 HValue* right, 7899 HValue* right,
7729 Handle<Type> left_type, 7900 Handle<Type> left_type,
7730 Handle<Type> right_type, 7901 Handle<Type> right_type,
7731 Handle<Type> result_type, 7902 Handle<Type> result_type,
7732 Maybe<int> fixed_right_arg, 7903 Maybe<int> fixed_right_arg) {
7733 HValue* context) {
7734 7904
7735 Representation left_rep = Representation::FromType(left_type); 7905 Representation left_rep = Representation::FromType(left_type);
7736 Representation right_rep = Representation::FromType(right_type); 7906 Representation right_rep = Representation::FromType(right_type);
7737 7907
7738 bool maybe_string_add = op == Token::ADD && 7908 bool maybe_string_add = op == Token::ADD &&
7739 (left_type->Maybe(Type::String()) || 7909 (left_type->Maybe(Type::String()) ||
7740 right_type->Maybe(Type::String())); 7910 right_type->Maybe(Type::String()));
7741 7911
7742 if (left_type->Is(Type::None())) { 7912 if (left_type->Is(Type::None())) {
7743 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 7913 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
(...skipping 30 matching lines...) Expand all
7774 BuildCheckHeapObject(left); 7944 BuildCheckHeapObject(left);
7775 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 7945 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
7776 flags = STRING_ADD_CHECK_RIGHT; 7946 flags = STRING_ADD_CHECK_RIGHT;
7777 } 7947 }
7778 if (right_type->Is(Type::String())) { 7948 if (right_type->Is(Type::String())) {
7779 BuildCheckHeapObject(right); 7949 BuildCheckHeapObject(right);
7780 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 7950 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
7781 flags = (flags == STRING_ADD_CHECK_BOTH) 7951 flags = (flags == STRING_ADD_CHECK_BOTH)
7782 ? STRING_ADD_CHECK_LEFT : STRING_ADD_CHECK_NONE; 7952 ? STRING_ADD_CHECK_LEFT : STRING_ADD_CHECK_NONE;
7783 } 7953 }
7784 instr = HStringAdd::New(zone(), context, left, right, flags); 7954 instr = NewUncasted<HStringAdd>(left, right, flags);
7785 } else { 7955 } else {
7786 instr = HAdd::New(zone(), context, left, right); 7956 instr = NewUncasted<HAdd>(left, right);
7787 } 7957 }
7788 break; 7958 break;
7789 case Token::SUB: 7959 case Token::SUB:
7790 instr = HSub::New(zone(), context, left, right); 7960 instr = NewUncasted<HSub>(left, right);
7791 break; 7961 break;
7792 case Token::MUL: 7962 case Token::MUL:
7793 instr = HMul::New(zone(), context, left, right); 7963 instr = NewUncasted<HMul>(left, right);
7794 break; 7964 break;
7795 case Token::MOD: 7965 case Token::MOD:
7796 instr = HMod::New(zone(), context, left, right, fixed_right_arg); 7966 instr = NewUncasted<HMod>(left, right, fixed_right_arg);
7797 break; 7967 break;
7798 case Token::DIV: 7968 case Token::DIV:
7799 instr = HDiv::New(zone(), context, left, right); 7969 instr = NewUncasted<HDiv>(left, right);
7800 break; 7970 break;
7801 case Token::BIT_XOR: 7971 case Token::BIT_XOR:
7802 case Token::BIT_AND: 7972 case Token::BIT_AND:
7803 instr = NewUncasted<HBitwise>(op, left, right); 7973 instr = NewUncasted<HBitwise>(op, left, right);
7804 break; 7974 break;
7805 case Token::BIT_OR: { 7975 case Token::BIT_OR: {
7806 HValue* operand, *shift_amount; 7976 HValue* operand, *shift_amount;
7807 if (left_type->Is(Type::Signed32()) && 7977 if (left_type->Is(Type::Signed32()) &&
7808 right_type->Is(Type::Signed32()) && 7978 right_type->Is(Type::Signed32()) &&
7809 MatchRotateRight(left, right, &operand, &shift_amount)) { 7979 MatchRotateRight(left, right, &operand, &shift_amount)) {
7810 instr = new(zone()) HRor(context, operand, shift_amount); 7980 instr = NewUncasted<HRor>(operand, shift_amount);
7811 } else { 7981 } else {
7812 instr = NewUncasted<HBitwise>(op, left, right); 7982 instr = NewUncasted<HBitwise>(op, left, right);
7813 } 7983 }
7814 break; 7984 break;
7815 } 7985 }
7816 case Token::SAR: 7986 case Token::SAR:
7817 instr = HSar::New(zone(), context, left, right); 7987 instr = NewUncasted<HSar>(left, right);
7818 break; 7988 break;
7819 case Token::SHR: 7989 case Token::SHR:
7820 instr = HShr::New(zone(), context, left, right); 7990 instr = NewUncasted<HShr>(left, right);
7821 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 7991 if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
7822 CanBeZero(right)) { 7992 CanBeZero(right)) {
7823 graph()->RecordUint32Instruction(instr); 7993 graph()->RecordUint32Instruction(instr);
7824 } 7994 }
7825 break; 7995 break;
7826 case Token::SHL: 7996 case Token::SHL:
7827 instr = HShl::New(zone(), context, left, right); 7997 instr = NewUncasted<HShl>(left, right);
7828 break; 7998 break;
7829 default: 7999 default:
7830 UNREACHABLE(); 8000 UNREACHABLE();
7831 } 8001 }
7832 8002
7833 if (instr->IsBinaryOperation()) { 8003 if (instr->IsBinaryOperation()) {
7834 HBinaryOperation* binop = HBinaryOperation::cast(instr); 8004 HBinaryOperation* binop = HBinaryOperation::cast(instr);
7835 binop->set_observed_input_representation(1, left_rep); 8005 binop->set_observed_input_representation(1, left_rep);
7836 binop->set_observed_input_representation(2, right_rep); 8006 binop->set_observed_input_representation(2, right_rep);
7837 binop->initialize_output_representation(result_rep); 8007 binop->initialize_output_representation(result_rep);
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
8230 Handle<JSObject> boilerplate_object, 8400 Handle<JSObject> boilerplate_object,
8231 Handle<Object> allocation_site_object, 8401 Handle<Object> allocation_site_object,
8232 AllocationSiteMode mode) { 8402 AllocationSiteMode mode) {
8233 NoObservableSideEffectsScope no_effects(this); 8403 NoObservableSideEffectsScope no_effects(this);
8234 8404
8235 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 8405 Handle<FixedArrayBase> elements(boilerplate_object->elements());
8236 int object_size = boilerplate_object->map()->instance_size(); 8406 int object_size = boilerplate_object->map()->instance_size();
8237 int object_offset = object_size; 8407 int object_offset = object_size;
8238 8408
8239 InstanceType instance_type = boilerplate_object->map()->instance_type(); 8409 InstanceType instance_type = boilerplate_object->map()->instance_type();
8240 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE && 8410 bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE;
8241 AllocationSite::CanTrack(instance_type);
8242 8411
8243 // If using allocation sites, then the payload on the site should already 8412 // If using allocation sites, then
8244 // be filled in as a valid (boilerplate) array. 8413 // 1) the payload on the site should already be filled in as a valid
8414 // (boilerplate) array, and
8415 // 2) we shouldn't be pretenuring the allocations.
8245 ASSERT(!create_allocation_site_info || 8416 ASSERT(!create_allocation_site_info ||
8246 AllocationSite::cast(*allocation_site_object)->IsLiteralSite()); 8417 (AllocationSite::cast(*allocation_site_object)->IsLiteralSite() &&
8418 isolate()->heap()->GetPretenureMode() == NOT_TENURED));
8247 8419
8248 if (create_allocation_site_info) { 8420 if (create_allocation_site_info) {
8249 object_size += AllocationMemento::kSize; 8421 object_size += AllocationMemento::kSize;
8250 } 8422 }
8251 8423
8252 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 8424 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
8253 HType type = instance_type == JS_ARRAY_TYPE 8425 HType type = instance_type == JS_ARRAY_TYPE
8254 ? HType::JSArray() : HType::JSObject(); 8426 ? HType::JSArray() : HType::JSObject();
8255 HValue* object_size_constant = Add<HConstant>(object_size); 8427 HValue* object_size_constant = Add<HConstant>(object_size);
8256 HInstruction* object = Add<HAllocate>(object_size_constant, type, 8428 HInstruction* object = Add<HAllocate>(object_size_constant, type,
8257 isolate()->heap()->GetPretenureMode(), instance_type); 8429 isolate()->heap()->GetPretenureMode(), instance_type);
8258 8430
8259
8260 BuildEmitObjectHeader(boilerplate_object, object); 8431 BuildEmitObjectHeader(boilerplate_object, object);
8261 8432
8262 if (create_allocation_site_info) { 8433 if (create_allocation_site_info) {
8263 HInstruction* allocation_site = Add<HConstant>(allocation_site_object); 8434 HInstruction* allocation_site = Add<HConstant>(allocation_site_object);
8264 BuildCreateAllocationMemento(object, object_offset, allocation_site); 8435 BuildCreateAllocationMemento(object, object_offset, allocation_site);
8265 } 8436 }
8266 8437
8267 int elements_size = (elements->length() > 0 && 8438 int elements_size = (elements->length() > 0 &&
8268 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 8439 elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
8269 elements->Size() : 0; 8440 elements->Size() : 0;
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
8968 9139
8969 // Support for fast native caches. 9140 // Support for fast native caches.
8970 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 9141 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
8971 return Bailout(kInlinedRuntimeFunctionGetFromCache); 9142 return Bailout(kInlinedRuntimeFunctionGetFromCache);
8972 } 9143 }
8973 9144
8974 9145
8975 // Fast support for number to string. 9146 // Fast support for number to string.
8976 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 9147 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
8977 ASSERT_EQ(1, call->arguments()->length()); 9148 ASSERT_EQ(1, call->arguments()->length());
8978 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9149 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8979 HValue* context = environment()->context(); 9150 HValue* number = Pop();
8980 HCallStub* result = 9151 HValue* result = BuildNumberToString(number);
8981 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 9152 return ast_context()->ReturnValue(result);
8982 Drop(1);
8983 return ast_context()->ReturnInstruction(result, call->id());
8984 } 9153 }
8985 9154
8986 9155
8987 // Fast call for custom callbacks. 9156 // Fast call for custom callbacks.
8988 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 9157 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
8989 // 1 ~ The function to call is not itself an argument to the call. 9158 // 1 ~ The function to call is not itself an argument to the call.
8990 int arg_count = call->arguments()->length() - 1; 9159 int arg_count = call->arguments()->length() - 1;
8991 ASSERT(arg_count >= 1); // There's always at least a receiver. 9160 ASSERT(arg_count >= 1); // There's always at least a receiver.
8992 9161
8993 for (int i = 0; i < arg_count; ++i) { 9162 for (int i = 0; i < arg_count; ++i) {
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
9740 if (ShouldProduceTraceOutput()) { 9909 if (ShouldProduceTraceOutput()) {
9741 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9910 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9742 } 9911 }
9743 9912
9744 #ifdef DEBUG 9913 #ifdef DEBUG
9745 graph_->Verify(false); // No full verify. 9914 graph_->Verify(false); // No full verify.
9746 #endif 9915 #endif
9747 } 9916 }
9748 9917
9749 } } // namespace v8::internal 9918 } } // 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