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

Side by Side Diff: src/hydrogen.cc

Issue 900223002: Revert of Externalize deoptimization reasons. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
« 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 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 DCHECK(did_then_); 924 DCHECK(did_then_);
925 DCHECK(!captured_); 925 DCHECK(!captured_);
926 DCHECK(!finished_); 926 DCHECK(!finished_);
927 AddMergeAtJoinBlock(false); 927 AddMergeAtJoinBlock(false);
928 builder()->set_current_block(first_false_block_); 928 builder()->set_current_block(first_false_block_);
929 pending_merge_block_ = true; 929 pending_merge_block_ = true;
930 did_else_ = true; 930 did_else_ = true;
931 } 931 }
932 932
933 933
934 void HGraphBuilder::IfBuilder::Deopt(Deoptimizer::DeoptReason reason) { 934 void HGraphBuilder::IfBuilder::Deopt(const char* reason) {
935 DCHECK(did_then_); 935 DCHECK(did_then_);
936 builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER); 936 builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER);
937 AddMergeAtJoinBlock(true); 937 AddMergeAtJoinBlock(true);
938 } 938 }
939 939
940 940
941 void HGraphBuilder::IfBuilder::Return(HValue* value) { 941 void HGraphBuilder::IfBuilder::Return(HValue* value) {
942 HValue* parameter_count = builder()->graph()->GetConstantMinus1(); 942 HValue* parameter_count = builder()->graph()->GetConstantMinus1();
943 builder()->FinishExitCurrentBlock( 943 builder()->FinishExitCurrentBlock(
944 builder()->New<HReturn>(value, parameter_count)); 944 builder()->New<HReturn>(value, parameter_count));
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 return BuildDecodeField<Map::ElementsKindBits>(bit_field2); 1266 return BuildDecodeField<Map::ElementsKindBits>(bit_field2);
1267 } 1267 }
1268 1268
1269 1269
1270 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1270 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1271 if (obj->type().IsHeapObject()) return obj; 1271 if (obj->type().IsHeapObject()) return obj;
1272 return Add<HCheckHeapObject>(obj); 1272 return Add<HCheckHeapObject>(obj);
1273 } 1273 }
1274 1274
1275 1275
1276 void HGraphBuilder::FinishExitWithHardDeoptimization( 1276 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
1277 Deoptimizer::DeoptReason reason) {
1278 Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1277 Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1279 FinishExitCurrentBlock(New<HAbnormalExit>()); 1278 FinishExitCurrentBlock(New<HAbnormalExit>());
1280 } 1279 }
1281 1280
1282 1281
1283 HValue* HGraphBuilder::BuildCheckString(HValue* string) { 1282 HValue* HGraphBuilder::BuildCheckString(HValue* string) {
1284 if (!string->type().IsString()) { 1283 if (!string->type().IsString()) {
1285 DCHECK(!string->IsConstant() || 1284 DCHECK(!string->IsConstant() ||
1286 !HConstant::cast(string)->HasStringValue()); 1285 !HConstant::cast(string)->HasStringValue());
1287 BuildCheckHeapObject(string); 1286 BuildCheckHeapObject(string);
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE); 1582 HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE);
1584 1583
1585 IfBuilder if_global_object(this); 1584 IfBuilder if_global_object(this);
1586 if_global_object.If<HCompareNumericAndBranch>(instance_type, 1585 if_global_object.If<HCompareNumericAndBranch>(instance_type,
1587 max_global_type, 1586 max_global_type,
1588 Token::LTE); 1587 Token::LTE);
1589 if_global_object.And(); 1588 if_global_object.And();
1590 if_global_object.If<HCompareNumericAndBranch>(instance_type, 1589 if_global_object.If<HCompareNumericAndBranch>(instance_type,
1591 min_global_type, 1590 min_global_type,
1592 Token::GTE); 1591 Token::GTE);
1593 if_global_object.ThenDeopt(Deoptimizer::kReceiverWasAGlobalObject); 1592 if_global_object.ThenDeopt("receiver was a global object");
1594 if_global_object.End(); 1593 if_global_object.End();
1595 } 1594 }
1596 1595
1597 1596
1598 void HGraphBuilder::BuildTestForDictionaryProperties( 1597 void HGraphBuilder::BuildTestForDictionaryProperties(
1599 HValue* object, 1598 HValue* object,
1600 HIfContinuation* continuation) { 1599 HIfContinuation* continuation) {
1601 HValue* properties = Add<HLoadNamedField>( 1600 HValue* properties = Add<HLoadNamedField>(
1602 object, nullptr, HObjectAccess::ForPropertiesPointer()); 1601 object, nullptr, HObjectAccess::ForPropertiesPointer());
1603 HValue* properties_map = 1602 HValue* properties_map =
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1913 if_objectiskey.Then(); 1912 if_objectiskey.Then();
1914 { 1913 {
1915 // Make the key_index available. 1914 // Make the key_index available.
1916 Push(key_index); 1915 Push(key_index);
1917 } 1916 }
1918 if_objectiskey.JoinContinuation(&found); 1917 if_objectiskey.JoinContinuation(&found);
1919 } 1918 }
1920 if_objectissmi.Else(); 1919 if_objectissmi.Else();
1921 { 1920 {
1922 if (type->Is(Type::SignedSmall())) { 1921 if (type->Is(Type::SignedSmall())) {
1923 if_objectissmi.Deopt(Deoptimizer::kExpectedSmi); 1922 if_objectissmi.Deopt("Expected smi");
1924 } else { 1923 } else {
1925 // Check if the object is a heap number. 1924 // Check if the object is a heap number.
1926 IfBuilder if_objectisnumber(this); 1925 IfBuilder if_objectisnumber(this);
1927 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( 1926 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>(
1928 object, isolate()->factory()->heap_number_map()); 1927 object, isolate()->factory()->heap_number_map());
1929 if_objectisnumber.Then(); 1928 if_objectisnumber.Then();
1930 { 1929 {
1931 // Compute hash for heap number similar to double_get_hash(). 1930 // Compute hash for heap number similar to double_get_hash().
1932 HValue* low = Add<HLoadNamedField>( 1931 HValue* low = Add<HLoadNamedField>(
1933 object, objectisnumber, 1932 object, objectisnumber,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 } 1967 }
1969 if_keyeqobject.JoinContinuation(&found); 1968 if_keyeqobject.JoinContinuation(&found);
1970 } 1969 }
1971 if_keyisheapnumber.JoinContinuation(&found); 1970 if_keyisheapnumber.JoinContinuation(&found);
1972 } 1971 }
1973 if_keyisnotsmi.JoinContinuation(&found); 1972 if_keyisnotsmi.JoinContinuation(&found);
1974 } 1973 }
1975 if_objectisnumber.Else(); 1974 if_objectisnumber.Else();
1976 { 1975 {
1977 if (type->Is(Type::Number())) { 1976 if (type->Is(Type::Number())) {
1978 if_objectisnumber.Deopt(Deoptimizer::kExpectedHeapNumber); 1977 if_objectisnumber.Deopt("Expected heap number");
1979 } 1978 }
1980 } 1979 }
1981 if_objectisnumber.JoinContinuation(&found); 1980 if_objectisnumber.JoinContinuation(&found);
1982 } 1981 }
1983 } 1982 }
1984 if_objectissmi.JoinContinuation(&found); 1983 if_objectissmi.JoinContinuation(&found);
1985 1984
1986 // Check for cache hit. 1985 // Check for cache hit.
1987 IfBuilder if_found(this, &found); 1986 IfBuilder if_found(this, &found);
1988 if_found.Then(); 1987 if_found.Then();
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 NoObservableSideEffectsScope no_effects(this); 2440 NoObservableSideEffectsScope no_effects(this);
2442 IfBuilder length_checker(this); 2441 IfBuilder length_checker(this);
2443 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2442 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
2444 length_checker.Then(); 2443 length_checker.Then();
2445 IfBuilder negative_checker(this); 2444 IfBuilder negative_checker(this);
2446 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2445 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
2447 key, graph()->GetConstant0(), Token::GTE); 2446 key, graph()->GetConstant0(), Token::GTE);
2448 negative_checker.Then(); 2447 negative_checker.Then();
2449 HInstruction* result = AddElementAccess( 2448 HInstruction* result = AddElementAccess(
2450 backing_store, key, val, bounds_check, elements_kind, access_type); 2449 backing_store, key, val, bounds_check, elements_kind, access_type);
2451 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); 2450 negative_checker.ElseDeopt("Negative key encountered");
2452 negative_checker.End(); 2451 negative_checker.End();
2453 length_checker.End(); 2452 length_checker.End();
2454 return result; 2453 return result;
2455 } else { 2454 } else {
2456 DCHECK(store_mode == STANDARD_STORE); 2455 DCHECK(store_mode == STANDARD_STORE);
2457 checked_key = Add<HBoundsCheck>(key, length); 2456 checked_key = Add<HBoundsCheck>(key, length);
2458 return AddElementAccess( 2457 return AddElementAccess(
2459 backing_store, checked_key, val, 2458 backing_store, checked_key, val,
2460 checked_object, elements_kind, access_type); 2459 checked_object, elements_kind, access_type);
2461 } 2460 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2526 Token::EQ); 2525 Token::EQ);
2527 if_builder.Then(); 2526 if_builder.Then();
2528 const int initial_capacity = JSArray::kPreallocatedArrayElements; 2527 const int initial_capacity = JSArray::kPreallocatedArrayElements;
2529 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); 2528 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
2530 Push(initial_capacity_node); // capacity 2529 Push(initial_capacity_node); // capacity
2531 Push(constant_zero); // length 2530 Push(constant_zero); // length
2532 if_builder.Else(); 2531 if_builder.Else();
2533 if (!(top_info()->IsStub()) && 2532 if (!(top_info()->IsStub()) &&
2534 IsFastPackedElementsKind(array_builder->kind())) { 2533 IsFastPackedElementsKind(array_builder->kind())) {
2535 // We'll come back later with better (holey) feedback. 2534 // We'll come back later with better (holey) feedback.
2536 if_builder.Deopt( 2535 if_builder.Deopt("Holey array despite packed elements_kind feedback");
2537 Deoptimizer::kHoleyArrayDespitePackedElements_kindFeedback);
2538 } else { 2536 } else {
2539 Push(checked_length); // capacity 2537 Push(checked_length); // capacity
2540 Push(checked_length); // length 2538 Push(checked_length); // length
2541 } 2539 }
2542 if_builder.End(); 2540 if_builder.End();
2543 2541
2544 // Figure out total size 2542 // Figure out total size
2545 HValue* length = Pop(); 2543 HValue* length = Pop();
2546 HValue* capacity = Pop(); 2544 HValue* capacity = Pop();
2547 return array_builder->AllocateArray(capacity, max_alloc_length, length); 2545 return array_builder->AllocateArray(capacity, max_alloc_length, length);
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 // emitted below is the actual monomorphic map. 3064 // emitted below is the actual monomorphic map.
3067 if (map_embedding == kEmbedMapsViaWeakCells) { 3065 if (map_embedding == kEmbedMapsViaWeakCells) {
3068 HValue* cell = 3066 HValue* cell =
3069 Add<HConstant>(Map::WeakCellForMap(type->Classes().Current())); 3067 Add<HConstant>(Map::WeakCellForMap(type->Classes().Current()));
3070 HValue* expected_map = Add<HLoadNamedField>( 3068 HValue* expected_map = Add<HLoadNamedField>(
3071 cell, nullptr, HObjectAccess::ForWeakCellValue()); 3069 cell, nullptr, HObjectAccess::ForWeakCellValue());
3072 HValue* map = 3070 HValue* map =
3073 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap()); 3071 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap());
3074 IfBuilder map_check(this); 3072 IfBuilder map_check(this);
3075 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map); 3073 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map);
3076 map_check.ThenDeopt(Deoptimizer::kUnknownMap); 3074 map_check.ThenDeopt("Unknown map");
3077 map_check.End(); 3075 map_check.End();
3078 } else { 3076 } else {
3079 DCHECK(map_embedding == kEmbedMapsDirectly); 3077 DCHECK(map_embedding == kEmbedMapsDirectly);
3080 Add<HCheckMaps>(value, type->Classes().Current()); 3078 Add<HCheckMaps>(value, type->Classes().Current());
3081 } 3079 }
3082 } else { 3080 } else {
3083 if_nil.Deopt(Deoptimizer::kTooManyUndetectableTypes); 3081 if_nil.Deopt("Too many undetectable types");
3084 } 3082 }
3085 } 3083 }
3086 3084
3087 if_nil.CaptureContinuation(continuation); 3085 if_nil.CaptureContinuation(continuation);
3088 } 3086 }
3089 3087
3090 3088
3091 void HGraphBuilder::BuildCreateAllocationMemento( 3089 void HGraphBuilder::BuildCreateAllocationMemento(
3092 HValue* previous_object, 3090 HValue* previous_object,
3093 HValue* previous_object_size, 3091 HValue* previous_object_size,
(...skipping 3309 matching lines...) Expand 10 before | Expand all | Expand 10 after
6403 } 6401 }
6404 6402
6405 if (current_block() != NULL) Goto(join); 6403 if (current_block() != NULL) Goto(join);
6406 set_current_block(if_false); 6404 set_current_block(if_false);
6407 } 6405 }
6408 6406
6409 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6407 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6410 // know about and do not want to handle ones we've never seen. Otherwise 6408 // know about and do not want to handle ones we've never seen. Otherwise
6411 // use a generic IC. 6409 // use a generic IC.
6412 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6410 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6413 FinishExitWithHardDeoptimization( 6411 FinishExitWithHardDeoptimization("Unknown map in polymorphic access");
6414 Deoptimizer::kUnknownMapInPolymorphicAccess);
6415 } else { 6412 } else {
6416 HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name, 6413 HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name,
6417 value); 6414 value);
6418 AddInstruction(instr); 6415 AddInstruction(instr);
6419 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 6416 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
6420 6417
6421 if (join != NULL) { 6418 if (join != NULL) {
6422 Goto(join); 6419 Goto(join);
6423 } else { 6420 } else {
6424 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6421 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
6551 6548
6552 LookupIterator it(global, var->name(), LookupIterator::OWN_SKIP_INTERCEPTOR); 6549 LookupIterator it(global, var->name(), LookupIterator::OWN_SKIP_INTERCEPTOR);
6553 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 6550 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE);
6554 if (type == kUseCell) { 6551 if (type == kUseCell) {
6555 Handle<PropertyCell> cell = it.GetPropertyCell(); 6552 Handle<PropertyCell> cell = it.GetPropertyCell();
6556 if (cell->type()->IsConstant()) { 6553 if (cell->type()->IsConstant()) {
6557 Handle<Object> constant = cell->type()->AsConstant()->Value(); 6554 Handle<Object> constant = cell->type()->AsConstant()->Value();
6558 if (value->IsConstant()) { 6555 if (value->IsConstant()) {
6559 HConstant* c_value = HConstant::cast(value); 6556 HConstant* c_value = HConstant::cast(value);
6560 if (!constant.is_identical_to(c_value->handle(isolate()))) { 6557 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6561 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, 6558 Add<HDeoptimize>("Constant global variable assignment",
6562 Deoptimizer::EAGER); 6559 Deoptimizer::EAGER);
6563 } 6560 }
6564 } else { 6561 } else {
6565 HValue* c_constant = Add<HConstant>(constant); 6562 HValue* c_constant = Add<HConstant>(constant);
6566 IfBuilder builder(this); 6563 IfBuilder builder(this);
6567 if (constant->IsNumber()) { 6564 if (constant->IsNumber()) {
6568 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); 6565 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ);
6569 } else { 6566 } else {
6570 builder.If<HCompareObjectEqAndBranch>(value, c_constant); 6567 builder.If<HCompareObjectEqAndBranch>(value, c_constant);
6571 } 6568 }
6572 builder.Then(); 6569 builder.Then();
6573 builder.Else(); 6570 builder.Else();
6574 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, 6571 Add<HDeoptimize>("Constant global variable assignment",
6575 Deoptimizer::EAGER); 6572 Deoptimizer::EAGER);
6576 builder.End(); 6573 builder.End();
6577 } 6574 }
6578 } 6575 }
6579 HInstruction* instr = 6576 HInstruction* instr =
6580 Add<HStoreGlobalCell>(value, cell, it.property_details()); 6577 Add<HStoreGlobalCell>(value, cell, it.property_details());
6581 if (instr->HasObservableSideEffects()) { 6578 if (instr->HasObservableSideEffects()) {
6582 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6579 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6583 } 6580 }
6584 } else { 6581 } else {
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
6884 6881
6885 6882
6886 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 6883 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
6887 PropertyAccessType access_type, 6884 PropertyAccessType access_type,
6888 Expression* expr, 6885 Expression* expr,
6889 HValue* object, 6886 HValue* object,
6890 Handle<String> name, 6887 Handle<String> name,
6891 HValue* value, 6888 HValue* value,
6892 bool is_uninitialized) { 6889 bool is_uninitialized) {
6893 if (is_uninitialized) { 6890 if (is_uninitialized) {
6894 Add<HDeoptimize>( 6891 Add<HDeoptimize>("Insufficient type feedback for generic named access",
6895 Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess, 6892 Deoptimizer::SOFT);
6896 Deoptimizer::SOFT);
6897 } 6893 }
6898 if (access_type == LOAD) { 6894 if (access_type == LOAD) {
6899 HLoadNamedGeneric* result = New<HLoadNamedGeneric>(object, name); 6895 HLoadNamedGeneric* result = New<HLoadNamedGeneric>(object, name);
6900 if (FLAG_vector_ics) { 6896 if (FLAG_vector_ics) {
6901 Handle<SharedFunctionInfo> current_shared = 6897 Handle<SharedFunctionInfo> current_shared =
6902 function_state()->compilation_info()->shared_info(); 6898 function_state()->compilation_info()->shared_info();
6903 Handle<TypeFeedbackVector> vector = 6899 Handle<TypeFeedbackVector> vector =
6904 handle(current_shared->feedback_vector(), isolate()); 6900 handle(current_shared->feedback_vector(), isolate());
6905 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); 6901 FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
6906 result->SetVectorAndSlot(vector, slot); 6902 result->SetVectorAndSlot(vector, slot);
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
7188 set_current_block(other_map); 7184 set_current_block(other_map);
7189 } 7185 }
7190 7186
7191 // Ensure that we visited at least one map above that goes to join. This is 7187 // Ensure that we visited at least one map above that goes to join. This is
7192 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit 7188 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit
7193 // rather than joining the join block. If this becomes an issue, insert a 7189 // rather than joining the join block. If this becomes an issue, insert a
7194 // generic access in the case length() == 0. 7190 // generic access in the case length() == 0.
7195 DCHECK(join->predecessors()->length() > 0); 7191 DCHECK(join->predecessors()->length() > 0);
7196 // Deopt if none of the cases matched. 7192 // Deopt if none of the cases matched.
7197 NoObservableSideEffectsScope scope(this); 7193 NoObservableSideEffectsScope scope(this);
7198 FinishExitWithHardDeoptimization( 7194 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access");
7199 Deoptimizer::kUnknownMapInPolymorphicElementAccess);
7200 set_current_block(join); 7195 set_current_block(join);
7201 return access_type == STORE ? val : Pop(); 7196 return access_type == STORE ? val : Pop();
7202 } 7197 }
7203 7198
7204 7199
7205 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 7200 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
7206 HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id, 7201 HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id,
7207 BailoutId return_id, PropertyAccessType access_type, 7202 BailoutId return_id, PropertyAccessType access_type,
7208 bool* has_side_effects) { 7203 bool* has_side_effects) {
7209 // TODO(mvstanton): This optimization causes trouble for vector-based 7204 // TODO(mvstanton): This optimization causes trouble for vector-based
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
7284 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); 7279 obj, key, val, NULL, map, access_type, expr->GetStoreMode());
7285 } 7280 }
7286 } else if (!force_generic && (types != NULL && !types->is_empty())) { 7281 } else if (!force_generic && (types != NULL && !types->is_empty())) {
7287 return HandlePolymorphicElementAccess( 7282 return HandlePolymorphicElementAccess(
7288 expr, obj, key, val, types, access_type, 7283 expr, obj, key, val, types, access_type,
7289 expr->GetStoreMode(), has_side_effects); 7284 expr->GetStoreMode(), has_side_effects);
7290 } else { 7285 } else {
7291 if (access_type == STORE) { 7286 if (access_type == STORE) {
7292 if (expr->IsAssignment() && 7287 if (expr->IsAssignment() &&
7293 expr->AsAssignment()->HasNoTypeInformation()) { 7288 expr->AsAssignment()->HasNoTypeInformation()) {
7294 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedStore, 7289 Add<HDeoptimize>("Insufficient type feedback for keyed store",
7295 Deoptimizer::SOFT); 7290 Deoptimizer::SOFT);
7296 } 7291 }
7297 } else { 7292 } else {
7298 if (expr->AsProperty()->HasNoTypeInformation()) { 7293 if (expr->AsProperty()->HasNoTypeInformation()) {
7299 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedLoad, 7294 Add<HDeoptimize>("Insufficient type feedback for keyed load",
7300 Deoptimizer::SOFT); 7295 Deoptimizer::SOFT);
7301 } 7296 }
7302 } 7297 }
7303 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val)); 7298 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val));
7304 } 7299 }
7305 *has_side_effects = instr->HasObservableSideEffects(); 7300 *has_side_effects = instr->HasObservableSideEffects();
7306 return instr; 7301 return instr;
7307 } 7302 }
7308 7303
7309 7304
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
7734 } 7729 }
7735 7730
7736 if (current_block() != NULL) Goto(join); 7731 if (current_block() != NULL) Goto(join);
7737 set_current_block(if_false); 7732 set_current_block(if_false);
7738 } 7733 }
7739 7734
7740 // Finish up. Unconditionally deoptimize if we've handled all the maps we 7735 // Finish up. Unconditionally deoptimize if we've handled all the maps we
7741 // know about and do not want to handle ones we've never seen. Otherwise 7736 // know about and do not want to handle ones we've never seen. Otherwise
7742 // use a generic IC. 7737 // use a generic IC.
7743 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 7738 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
7744 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); 7739 FinishExitWithHardDeoptimization("Unknown map in polymorphic call");
7745 } else { 7740 } else {
7746 Property* prop = expr->expression()->AsProperty(); 7741 Property* prop = expr->expression()->AsProperty();
7747 HInstruction* function = BuildNamedGeneric( 7742 HInstruction* function = BuildNamedGeneric(
7748 LOAD, prop, receiver, name, NULL, prop->IsUninitialized()); 7743 LOAD, prop, receiver, name, NULL, prop->IsUninitialized());
7749 AddInstruction(function); 7744 AddInstruction(function);
7750 Push(function); 7745 Push(function);
7751 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7746 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7752 7747
7753 environment()->SetExpressionStackAt(1, function); 7748 environment()->SetExpressionStackAt(1, function);
7754 environment()->SetExpressionStackAt(0, receiver); 7749 environment()->SetExpressionStackAt(0, receiver);
(...skipping 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after
9241 return; 9236 return;
9242 } else { 9237 } else {
9243 call = BuildCallConstantFunction(known_function, argument_count); 9238 call = BuildCallConstantFunction(known_function, argument_count);
9244 } 9239 }
9245 9240
9246 } else { 9241 } else {
9247 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9242 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9248 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9243 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9249 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9244 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9250 // gets ignored by the always-opt flag, which leads to incorrect code. 9245 // gets ignored by the always-opt flag, which leads to incorrect code.
9251 Add<HDeoptimize>( 9246 Add<HDeoptimize>("Insufficient type feedback for call with arguments",
9252 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9247 Deoptimizer::EAGER);
9253 Deoptimizer::EAGER);
9254 arguments_flag = ARGUMENTS_FAKED; 9248 arguments_flag = ARGUMENTS_FAKED;
9255 } 9249 }
9256 9250
9257 // Push the function under the receiver. 9251 // Push the function under the receiver.
9258 environment()->SetExpressionStackAt(0, function); 9252 environment()->SetExpressionStackAt(0, function);
9259 Push(receiver); 9253 Push(receiver);
9260 9254
9261 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9255 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9262 CallFunctionFlags flags = receiver->type().IsJSObject() 9256 CallFunctionFlags flags = receiver->type().IsJSObject()
9263 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; 9257 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after
10474 Representation left_rep = Representation::FromType(left_type); 10468 Representation left_rep = Representation::FromType(left_type);
10475 Representation right_rep = Representation::FromType(right_type); 10469 Representation right_rep = Representation::FromType(right_type);
10476 10470
10477 bool maybe_string_add = op == Token::ADD && 10471 bool maybe_string_add = op == Token::ADD &&
10478 (left_type->Maybe(Type::String()) || 10472 (left_type->Maybe(Type::String()) ||
10479 left_type->Maybe(Type::Receiver()) || 10473 left_type->Maybe(Type::Receiver()) ||
10480 right_type->Maybe(Type::String()) || 10474 right_type->Maybe(Type::String()) ||
10481 right_type->Maybe(Type::Receiver())); 10475 right_type->Maybe(Type::Receiver()));
10482 10476
10483 if (!left_type->IsInhabited()) { 10477 if (!left_type->IsInhabited()) {
10484 Add<HDeoptimize>( 10478 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
10485 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, 10479 Deoptimizer::SOFT);
10486 Deoptimizer::SOFT);
10487 // TODO(rossberg): we should be able to get rid of non-continuous 10480 // TODO(rossberg): we should be able to get rid of non-continuous
10488 // defaults. 10481 // defaults.
10489 left_type = Type::Any(zone()); 10482 left_type = Type::Any(zone());
10490 } else { 10483 } else {
10491 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); 10484 if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
10492 left_rep = Representation::FromType(left_type); 10485 left_rep = Representation::FromType(left_type);
10493 } 10486 }
10494 10487
10495 if (!right_type->IsInhabited()) { 10488 if (!right_type->IsInhabited()) {
10496 Add<HDeoptimize>( 10489 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
10497 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, 10490 Deoptimizer::SOFT);
10498 Deoptimizer::SOFT);
10499 right_type = Type::Any(zone()); 10491 right_type = Type::Any(zone());
10500 } else { 10492 } else {
10501 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); 10493 if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
10502 right_rep = Representation::FromType(right_type); 10494 right_rep = Representation::FromType(right_type);
10503 } 10495 }
10504 10496
10505 // Special case for string addition here. 10497 // Special case for string addition here.
10506 if (op == Token::ADD && 10498 if (op == Token::ADD &&
10507 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 10499 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
10508 // Validate type feedback for left argument. 10500 // Validate type feedback for left argument.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
10608 instr = AddUncasted<HMul>(left, right); 10600 instr = AddUncasted<HMul>(left, right);
10609 break; 10601 break;
10610 case Token::MOD: { 10602 case Token::MOD: {
10611 if (fixed_right_arg.has_value && 10603 if (fixed_right_arg.has_value &&
10612 !right->EqualsInteger32Constant(fixed_right_arg.value)) { 10604 !right->EqualsInteger32Constant(fixed_right_arg.value)) {
10613 HConstant* fixed_right = Add<HConstant>( 10605 HConstant* fixed_right = Add<HConstant>(
10614 static_cast<int>(fixed_right_arg.value)); 10606 static_cast<int>(fixed_right_arg.value));
10615 IfBuilder if_same(this); 10607 IfBuilder if_same(this);
10616 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); 10608 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
10617 if_same.Then(); 10609 if_same.Then();
10618 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); 10610 if_same.ElseDeopt("Unexpected RHS of binary operation");
10619 right = fixed_right; 10611 right = fixed_right;
10620 } 10612 }
10621 instr = AddUncasted<HMod>(left, right); 10613 instr = AddUncasted<HMod>(left, right);
10622 break; 10614 break;
10623 } 10615 }
10624 case Token::DIV: 10616 case Token::DIV:
10625 instr = AddUncasted<HDiv>(left, right); 10617 instr = AddUncasted<HDiv>(left, right);
10626 break; 10618 break;
10627 case Token::BIT_XOR: 10619 case Token::BIT_XOR:
10628 case Token::BIT_AND: 10620 case Token::BIT_AND:
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
10982 Type* left_type, 10974 Type* left_type,
10983 Type* right_type, 10975 Type* right_type,
10984 Type* combined_type, 10976 Type* combined_type,
10985 HSourcePosition left_position, 10977 HSourcePosition left_position,
10986 HSourcePosition right_position, 10978 HSourcePosition right_position,
10987 PushBeforeSimulateBehavior push_sim_result, 10979 PushBeforeSimulateBehavior push_sim_result,
10988 BailoutId bailout_id) { 10980 BailoutId bailout_id) {
10989 // Cases handled below depend on collected type feedback. They should 10981 // Cases handled below depend on collected type feedback. They should
10990 // soft deoptimize when there is no type feedback. 10982 // soft deoptimize when there is no type feedback.
10991 if (!combined_type->IsInhabited()) { 10983 if (!combined_type->IsInhabited()) {
10992 Add<HDeoptimize>( 10984 Add<HDeoptimize>("Insufficient type feedback for combined type "
10993 Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, 10985 "of binary operation",
10994 Deoptimizer::SOFT); 10986 Deoptimizer::SOFT);
10995 combined_type = left_type = right_type = Type::Any(zone()); 10987 combined_type = left_type = right_type = Type::Any(zone());
10996 } 10988 }
10997 10989
10998 Representation left_rep = Representation::FromType(left_type); 10990 Representation left_rep = Representation::FromType(left_type);
10999 Representation right_rep = Representation::FromType(right_type); 10991 Representation right_rep = Representation::FromType(right_type);
11000 Representation combined_rep = Representation::FromType(combined_type); 10992 Representation combined_rep = Representation::FromType(combined_type);
11001 10993
11002 if (combined_type->Is(Type::Receiver())) { 10994 if (combined_type->Is(Type::Receiver())) {
11003 if (Token::IsEqualityOp(op)) { 10995 if (Token::IsEqualityOp(op)) {
11004 // HCompareObjectEqAndBranch can only deal with object, so 10996 // HCompareObjectEqAndBranch can only deal with object, so
11005 // exclude numbers. 10997 // exclude numbers.
11006 if ((left->IsConstant() && 10998 if ((left->IsConstant() &&
11007 HConstant::cast(left)->HasNumberValue()) || 10999 HConstant::cast(left)->HasNumberValue()) ||
11008 (right->IsConstant() && 11000 (right->IsConstant() &&
11009 HConstant::cast(right)->HasNumberValue())) { 11001 HConstant::cast(right)->HasNumberValue())) {
11010 Add<HDeoptimize>(Deoptimizer::kTypeMismatchBetweenFeedbackAndConstant, 11002 Add<HDeoptimize>("Type mismatch between feedback and constant",
11011 Deoptimizer::SOFT); 11003 Deoptimizer::SOFT);
11012 // The caller expects a branch instruction, so make it happy. 11004 // The caller expects a branch instruction, so make it happy.
11013 return New<HBranch>(graph()->GetConstantTrue()); 11005 return New<HBranch>(graph()->GetConstantTrue());
11014 } 11006 }
11015 // Can we get away with map check and not instance type check? 11007 // Can we get away with map check and not instance type check?
11016 HValue* operand_to_check = 11008 HValue* operand_to_check =
11017 left->block()->block_id() < right->block()->block_id() ? left : right; 11009 left->block()->block_id() < right->block()->block_id() ? left : right;
11018 if (combined_type->IsClass()) { 11010 if (combined_type->IsClass()) {
11019 Handle<Map> map = combined_type->AsClass()->Map(); 11011 Handle<Map> map = combined_type->AsClass()->Map();
11020 AddCheckMap(operand_to_check, map); 11012 AddCheckMap(operand_to_check, map);
(...skipping 17 matching lines...) Expand all
11038 return NULL; 11030 return NULL;
11039 } 11031 }
11040 } else if (combined_type->Is(Type::InternalizedString()) && 11032 } else if (combined_type->Is(Type::InternalizedString()) &&
11041 Token::IsEqualityOp(op)) { 11033 Token::IsEqualityOp(op)) {
11042 // If we have a constant argument, it should be consistent with the type 11034 // If we have a constant argument, it should be consistent with the type
11043 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). 11035 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch).
11044 if ((left->IsConstant() && 11036 if ((left->IsConstant() &&
11045 !HConstant::cast(left)->HasInternalizedStringValue()) || 11037 !HConstant::cast(left)->HasInternalizedStringValue()) ||
11046 (right->IsConstant() && 11038 (right->IsConstant() &&
11047 !HConstant::cast(right)->HasInternalizedStringValue())) { 11039 !HConstant::cast(right)->HasInternalizedStringValue())) {
11048 Add<HDeoptimize>(Deoptimizer::kTypeMismatchBetweenFeedbackAndConstant, 11040 Add<HDeoptimize>("Type mismatch between feedback and constant",
11049 Deoptimizer::SOFT); 11041 Deoptimizer::SOFT);
11050 // The caller expects a branch instruction, so make it happy. 11042 // The caller expects a branch instruction, so make it happy.
11051 return New<HBranch>(graph()->GetConstantTrue()); 11043 return New<HBranch>(graph()->GetConstantTrue());
11052 } 11044 }
11053 BuildCheckHeapObject(left); 11045 BuildCheckHeapObject(left);
11054 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); 11046 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING);
11055 BuildCheckHeapObject(right); 11047 BuildCheckHeapObject(right);
11056 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); 11048 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING);
11057 HCompareObjectEqAndBranch* result = 11049 HCompareObjectEqAndBranch* result =
11058 New<HCompareObjectEqAndBranch>(left, right); 11050 New<HCompareObjectEqAndBranch>(left, right);
(...skipping 2429 matching lines...) Expand 10 before | Expand all | Expand 10 after
13488 if (ShouldProduceTraceOutput()) { 13480 if (ShouldProduceTraceOutput()) {
13489 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13481 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13490 } 13482 }
13491 13483
13492 #ifdef DEBUG 13484 #ifdef DEBUG
13493 graph_->Verify(false); // No full verify. 13485 graph_->Verify(false); // No full verify.
13494 #endif 13486 #endif
13495 } 13487 }
13496 13488
13497 } } // namespace v8::internal 13489 } } // 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