| OLD | NEW |
| 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 2111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2122 elements); | 2122 elements); |
| 2123 | 2123 |
| 2124 // Initialize the elements contents with undefined. | 2124 // Initialize the elements contents with undefined. |
| 2125 BuildFillElementsWithValue( | 2125 BuildFillElementsWithValue( |
| 2126 elements, elements_kind, graph()->GetConstant0(), length, | 2126 elements, elements_kind, graph()->GetConstant0(), length, |
| 2127 graph()->GetConstantUndefined()); | 2127 graph()->GetConstantUndefined()); |
| 2128 | 2128 |
| 2129 return result; | 2129 return result; |
| 2130 } | 2130 } |
| 2131 | 2131 |
| 2132 | 2132 HValue* HGraphBuilder::BuildNumberToString(HValue* object, AstType* type) { |
| 2133 HValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) { | |
| 2134 NoObservableSideEffectsScope scope(this); | 2133 NoObservableSideEffectsScope scope(this); |
| 2135 | 2134 |
| 2136 // Convert constant numbers at compile time. | 2135 // Convert constant numbers at compile time. |
| 2137 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { | 2136 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { |
| 2138 Handle<Object> number = HConstant::cast(object)->handle(isolate()); | 2137 Handle<Object> number = HConstant::cast(object)->handle(isolate()); |
| 2139 Handle<String> result = isolate()->factory()->NumberToString(number); | 2138 Handle<String> result = isolate()->factory()->NumberToString(number); |
| 2140 return Add<HConstant>(result); | 2139 return Add<HConstant>(result); |
| 2141 } | 2140 } |
| 2142 | 2141 |
| 2143 // Create a joinable continuation. | 2142 // Create a joinable continuation. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2173 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); | 2172 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); |
| 2174 if_objectiskey.Then(); | 2173 if_objectiskey.Then(); |
| 2175 { | 2174 { |
| 2176 // Make the key_index available. | 2175 // Make the key_index available. |
| 2177 Push(key_index); | 2176 Push(key_index); |
| 2178 } | 2177 } |
| 2179 if_objectiskey.JoinContinuation(&found); | 2178 if_objectiskey.JoinContinuation(&found); |
| 2180 } | 2179 } |
| 2181 if_objectissmi.Else(); | 2180 if_objectissmi.Else(); |
| 2182 { | 2181 { |
| 2183 if (type->Is(Type::SignedSmall())) { | 2182 if (type->Is(AstType::SignedSmall())) { |
| 2184 if_objectissmi.Deopt(DeoptimizeReason::kExpectedSmi); | 2183 if_objectissmi.Deopt(DeoptimizeReason::kExpectedSmi); |
| 2185 } else { | 2184 } else { |
| 2186 // Check if the object is a heap number. | 2185 // Check if the object is a heap number. |
| 2187 IfBuilder if_objectisnumber(this); | 2186 IfBuilder if_objectisnumber(this); |
| 2188 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( | 2187 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( |
| 2189 object, isolate()->factory()->heap_number_map()); | 2188 object, isolate()->factory()->heap_number_map()); |
| 2190 if_objectisnumber.Then(); | 2189 if_objectisnumber.Then(); |
| 2191 { | 2190 { |
| 2192 // Compute hash for heap number similar to double_get_hash(). | 2191 // Compute hash for heap number similar to double_get_hash(). |
| 2193 HValue* low = Add<HLoadNamedField>( | 2192 HValue* low = Add<HLoadNamedField>( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 Push(key_index); | 2228 Push(key_index); |
| 2230 } | 2229 } |
| 2231 if_keyeqobject.JoinContinuation(&found); | 2230 if_keyeqobject.JoinContinuation(&found); |
| 2232 } | 2231 } |
| 2233 if_keyisheapnumber.JoinContinuation(&found); | 2232 if_keyisheapnumber.JoinContinuation(&found); |
| 2234 } | 2233 } |
| 2235 if_keyisnotsmi.JoinContinuation(&found); | 2234 if_keyisnotsmi.JoinContinuation(&found); |
| 2236 } | 2235 } |
| 2237 if_objectisnumber.Else(); | 2236 if_objectisnumber.Else(); |
| 2238 { | 2237 { |
| 2239 if (type->Is(Type::Number())) { | 2238 if (type->Is(AstType::Number())) { |
| 2240 if_objectisnumber.Deopt(DeoptimizeReason::kExpectedHeapNumber); | 2239 if_objectisnumber.Deopt(DeoptimizeReason::kExpectedHeapNumber); |
| 2241 } | 2240 } |
| 2242 } | 2241 } |
| 2243 if_objectisnumber.JoinContinuation(&found); | 2242 if_objectisnumber.JoinContinuation(&found); |
| 2244 } | 2243 } |
| 2245 } | 2244 } |
| 2246 if_objectissmi.JoinContinuation(&found); | 2245 if_objectissmi.JoinContinuation(&found); |
| 2247 | 2246 |
| 2248 // Check for cache hit. | 2247 // Check for cache hit. |
| 2249 IfBuilder if_found(this, &found); | 2248 IfBuilder if_found(this, &found); |
| (...skipping 2742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4992 DCHECK(current_block() != NULL); | 4991 DCHECK(current_block() != NULL); |
| 4993 DCHECK(current_block()->HasPredecessor()); | 4992 DCHECK(current_block()->HasPredecessor()); |
| 4994 | 4993 |
| 4995 ZoneList<CaseClause*>* clauses = stmt->cases(); | 4994 ZoneList<CaseClause*>* clauses = stmt->cases(); |
| 4996 int clause_count = clauses->length(); | 4995 int clause_count = clauses->length(); |
| 4997 ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); | 4996 ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); |
| 4998 | 4997 |
| 4999 CHECK_ALIVE(VisitForValue(stmt->tag())); | 4998 CHECK_ALIVE(VisitForValue(stmt->tag())); |
| 5000 Add<HSimulate>(stmt->EntryId()); | 4999 Add<HSimulate>(stmt->EntryId()); |
| 5001 HValue* tag_value = Top(); | 5000 HValue* tag_value = Top(); |
| 5002 Type* tag_type = bounds_.get(stmt->tag()).lower; | 5001 AstType* tag_type = bounds_.get(stmt->tag()).lower; |
| 5003 | 5002 |
| 5004 // 1. Build all the tests, with dangling true branches | 5003 // 1. Build all the tests, with dangling true branches |
| 5005 BailoutId default_id = BailoutId::None(); | 5004 BailoutId default_id = BailoutId::None(); |
| 5006 for (int i = 0; i < clause_count; ++i) { | 5005 for (int i = 0; i < clause_count; ++i) { |
| 5007 CaseClause* clause = clauses->at(i); | 5006 CaseClause* clause = clauses->at(i); |
| 5008 if (clause->is_default()) { | 5007 if (clause->is_default()) { |
| 5009 body_blocks.Add(NULL, zone()); | 5008 body_blocks.Add(NULL, zone()); |
| 5010 if (default_id.IsNone()) default_id = clause->EntryId(); | 5009 if (default_id.IsNone()) default_id = clause->EntryId(); |
| 5011 continue; | 5010 continue; |
| 5012 } | 5011 } |
| 5013 | 5012 |
| 5014 // Generate a compare and branch. | 5013 // Generate a compare and branch. |
| 5015 CHECK_BAILOUT(VisitForValue(clause->label())); | 5014 CHECK_BAILOUT(VisitForValue(clause->label())); |
| 5016 if (current_block() == NULL) return Bailout(kUnsupportedSwitchStatement); | 5015 if (current_block() == NULL) return Bailout(kUnsupportedSwitchStatement); |
| 5017 HValue* label_value = Pop(); | 5016 HValue* label_value = Pop(); |
| 5018 | 5017 |
| 5019 Type* label_type = bounds_.get(clause->label()).lower; | 5018 AstType* label_type = bounds_.get(clause->label()).lower; |
| 5020 Type* combined_type = clause->compare_type(); | 5019 AstType* combined_type = clause->compare_type(); |
| 5021 HControlInstruction* compare = BuildCompareInstruction( | 5020 HControlInstruction* compare = BuildCompareInstruction( |
| 5022 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, | 5021 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, |
| 5023 combined_type, | 5022 combined_type, |
| 5024 ScriptPositionToSourcePosition(stmt->tag()->position()), | 5023 ScriptPositionToSourcePosition(stmt->tag()->position()), |
| 5025 ScriptPositionToSourcePosition(clause->label()->position()), | 5024 ScriptPositionToSourcePosition(clause->label()->position()), |
| 5026 PUSH_BEFORE_SIMULATE, clause->id()); | 5025 PUSH_BEFORE_SIMULATE, clause->id()); |
| 5027 | 5026 |
| 5028 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 5027 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
| 5029 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 5028 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
| 5030 body_blocks.Add(body_block, zone()); | 5029 body_blocks.Add(body_block, zone()); |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6208 Handle<Map> map) const { | 6207 Handle<Map> map) const { |
| 6209 DCHECK(IsFound()); | 6208 DCHECK(IsFound()); |
| 6210 DCHECK(number_ < map->NumberOfOwnDescriptors()); | 6209 DCHECK(number_ < map->NumberOfOwnDescriptors()); |
| 6211 return handle(map->instance_descriptors()->GetFieldType(number_), isolate()); | 6210 return handle(map->instance_descriptors()->GetFieldType(number_), isolate()); |
| 6212 } | 6211 } |
| 6213 | 6212 |
| 6214 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( | 6213 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( |
| 6215 PropertyAccessInfo* info) { | 6214 PropertyAccessInfo* info) { |
| 6216 if (!CanInlinePropertyAccess(map_)) return false; | 6215 if (!CanInlinePropertyAccess(map_)) return false; |
| 6217 | 6216 |
| 6218 // Currently only handle Type::Number as a polymorphic case. | 6217 // Currently only handle AstType::Number as a polymorphic case. |
| 6219 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber | 6218 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber |
| 6220 // instruction. | 6219 // instruction. |
| 6221 if (IsNumberType()) return false; | 6220 if (IsNumberType()) return false; |
| 6222 | 6221 |
| 6223 // Values are only compatible for monomorphic load if they all behave the same | 6222 // Values are only compatible for monomorphic load if they all behave the same |
| 6224 // regarding value wrappers. | 6223 // regarding value wrappers. |
| 6225 if (IsValueWrapped() != info->IsValueWrapped()) return false; | 6224 if (IsValueWrapped() != info->IsValueWrapped()) return false; |
| 6226 | 6225 |
| 6227 if (!LookupDescriptor()) return false; | 6226 if (!LookupDescriptor()) return false; |
| 6228 | 6227 |
| (...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7805 | 7804 |
| 7806 if (maps->length() > 0) { | 7805 if (maps->length() > 0) { |
| 7807 PropertyAccessInfo info(this, access, maps->first(), name); | 7806 PropertyAccessInfo info(this, access, maps->first(), name); |
| 7808 if (!info.CanAccessAsMonomorphic(maps)) { | 7807 if (!info.CanAccessAsMonomorphic(maps)) { |
| 7809 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, | 7808 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, |
| 7810 object, value, maps, name); | 7809 object, value, maps, name); |
| 7811 return NULL; | 7810 return NULL; |
| 7812 } | 7811 } |
| 7813 | 7812 |
| 7814 HValue* checked_object; | 7813 HValue* checked_object; |
| 7815 // Type::Number() is only supported by polymorphic load/call handling. | 7814 // AstType::Number() is only supported by polymorphic load/call handling. |
| 7816 DCHECK(!info.IsNumberType()); | 7815 DCHECK(!info.IsNumberType()); |
| 7817 BuildCheckHeapObject(object); | 7816 BuildCheckHeapObject(object); |
| 7818 if (AreStringTypes(maps)) { | 7817 if (AreStringTypes(maps)) { |
| 7819 checked_object = | 7818 checked_object = |
| 7820 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); | 7819 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); |
| 7821 } else { | 7820 } else { |
| 7822 checked_object = Add<HCheckMaps>(object, maps); | 7821 checked_object = Add<HCheckMaps>(object, maps); |
| 7823 } | 7822 } |
| 7824 return BuildMonomorphicAccess( | 7823 return BuildMonomorphicAccess( |
| 7825 &info, object, checked_object, value, ast_id, return_id); | 7824 &info, object, checked_object, value, ast_id, return_id); |
| (...skipping 2814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10640 } else { | 10639 } else { |
| 10641 materialize_true = NULL; | 10640 materialize_true = NULL; |
| 10642 } | 10641 } |
| 10643 | 10642 |
| 10644 HBasicBlock* join = | 10643 HBasicBlock* join = |
| 10645 CreateJoin(materialize_false, materialize_true, expr->id()); | 10644 CreateJoin(materialize_false, materialize_true, expr->id()); |
| 10646 set_current_block(join); | 10645 set_current_block(join); |
| 10647 if (join != NULL) return ast_context()->ReturnValue(Pop()); | 10646 if (join != NULL) return ast_context()->ReturnValue(Pop()); |
| 10648 } | 10647 } |
| 10649 | 10648 |
| 10650 | 10649 static Representation RepresentationFor(AstType* type) { |
| 10651 static Representation RepresentationFor(Type* type) { | |
| 10652 DisallowHeapAllocation no_allocation; | 10650 DisallowHeapAllocation no_allocation; |
| 10653 if (type->Is(Type::None())) return Representation::None(); | 10651 if (type->Is(AstType::None())) return Representation::None(); |
| 10654 if (type->Is(Type::SignedSmall())) return Representation::Smi(); | 10652 if (type->Is(AstType::SignedSmall())) return Representation::Smi(); |
| 10655 if (type->Is(Type::Signed32())) return Representation::Integer32(); | 10653 if (type->Is(AstType::Signed32())) return Representation::Integer32(); |
| 10656 if (type->Is(Type::Number())) return Representation::Double(); | 10654 if (type->Is(AstType::Number())) return Representation::Double(); |
| 10657 return Representation::Tagged(); | 10655 return Representation::Tagged(); |
| 10658 } | 10656 } |
| 10659 | 10657 |
| 10660 | 10658 |
| 10661 HInstruction* HOptimizedGraphBuilder::BuildIncrement( | 10659 HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
| 10662 bool returns_original_input, | 10660 bool returns_original_input, |
| 10663 CountOperation* expr) { | 10661 CountOperation* expr) { |
| 10664 // The input to the count operation is on top of the expression stack. | 10662 // The input to the count operation is on top of the expression stack. |
| 10665 Representation rep = RepresentationFor(expr->type()); | 10663 Representation rep = RepresentationFor(expr->type()); |
| 10666 if (rep.IsNone() || rep.IsTagged()) { | 10664 if (rep.IsNone() || rep.IsTagged()) { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10895 if (right->IsConstant()) { | 10893 if (right->IsConstant()) { |
| 10896 HConstant* right_const = HConstant::cast(right); | 10894 HConstant* right_const = HConstant::cast(right); |
| 10897 if (right_const->HasInteger32Value() && | 10895 if (right_const->HasInteger32Value() && |
| 10898 (right_const->Integer32Value() & 0x1f) != 0) { | 10896 (right_const->Integer32Value() & 0x1f) != 0) { |
| 10899 return false; | 10897 return false; |
| 10900 } | 10898 } |
| 10901 } | 10899 } |
| 10902 return true; | 10900 return true; |
| 10903 } | 10901 } |
| 10904 | 10902 |
| 10905 | 10903 HValue* HGraphBuilder::EnforceNumberType(HValue* number, AstType* expected) { |
| 10906 HValue* HGraphBuilder::EnforceNumberType(HValue* number, | 10904 if (expected->Is(AstType::SignedSmall())) { |
| 10907 Type* expected) { | |
| 10908 if (expected->Is(Type::SignedSmall())) { | |
| 10909 return AddUncasted<HForceRepresentation>(number, Representation::Smi()); | 10905 return AddUncasted<HForceRepresentation>(number, Representation::Smi()); |
| 10910 } | 10906 } |
| 10911 if (expected->Is(Type::Signed32())) { | 10907 if (expected->Is(AstType::Signed32())) { |
| 10912 return AddUncasted<HForceRepresentation>(number, | 10908 return AddUncasted<HForceRepresentation>(number, |
| 10913 Representation::Integer32()); | 10909 Representation::Integer32()); |
| 10914 } | 10910 } |
| 10915 return number; | 10911 return number; |
| 10916 } | 10912 } |
| 10917 | 10913 |
| 10918 | 10914 HValue* HGraphBuilder::TruncateToNumber(HValue* value, AstType** expected) { |
| 10919 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { | |
| 10920 if (value->IsConstant()) { | 10915 if (value->IsConstant()) { |
| 10921 HConstant* constant = HConstant::cast(value); | 10916 HConstant* constant = HConstant::cast(value); |
| 10922 Maybe<HConstant*> number = | 10917 Maybe<HConstant*> number = |
| 10923 constant->CopyToTruncatedNumber(isolate(), zone()); | 10918 constant->CopyToTruncatedNumber(isolate(), zone()); |
| 10924 if (number.IsJust()) { | 10919 if (number.IsJust()) { |
| 10925 *expected = Type::Number(); | 10920 *expected = AstType::Number(); |
| 10926 return AddInstruction(number.FromJust()); | 10921 return AddInstruction(number.FromJust()); |
| 10927 } | 10922 } |
| 10928 } | 10923 } |
| 10929 | 10924 |
| 10930 // We put temporary values on the stack, which don't correspond to anything | 10925 // We put temporary values on the stack, which don't correspond to anything |
| 10931 // in baseline code. Since nothing is observable we avoid recording those | 10926 // in baseline code. Since nothing is observable we avoid recording those |
| 10932 // pushes with a NoObservableSideEffectsScope. | 10927 // pushes with a NoObservableSideEffectsScope. |
| 10933 NoObservableSideEffectsScope no_effects(this); | 10928 NoObservableSideEffectsScope no_effects(this); |
| 10934 | 10929 |
| 10935 Type* expected_type = *expected; | 10930 AstType* expected_type = *expected; |
| 10936 | 10931 |
| 10937 // Separate the number type from the rest. | 10932 // Separate the number type from the rest. |
| 10938 Type* expected_obj = | 10933 AstType* expected_obj = |
| 10939 Type::Intersect(expected_type, Type::NonNumber(), zone()); | 10934 AstType::Intersect(expected_type, AstType::NonNumber(), zone()); |
| 10940 Type* expected_number = | 10935 AstType* expected_number = |
| 10941 Type::Intersect(expected_type, Type::Number(), zone()); | 10936 AstType::Intersect(expected_type, AstType::Number(), zone()); |
| 10942 | 10937 |
| 10943 // We expect to get a number. | 10938 // We expect to get a number. |
| 10944 // (We need to check first, since Type::None->Is(Type::Any()) == true. | 10939 // (We need to check first, since AstType::None->Is(AstType::Any()) == true. |
| 10945 if (expected_obj->Is(Type::None())) { | 10940 if (expected_obj->Is(AstType::None())) { |
| 10946 DCHECK(!expected_number->Is(Type::None())); | 10941 DCHECK(!expected_number->Is(AstType::None())); |
| 10947 return value; | 10942 return value; |
| 10948 } | 10943 } |
| 10949 | 10944 |
| 10950 if (expected_obj->Is(Type::Undefined())) { | 10945 if (expected_obj->Is(AstType::Undefined())) { |
| 10951 // This is already done by HChange. | 10946 // This is already done by HChange. |
| 10952 *expected = Type::Union(expected_number, Type::Number(), zone()); | 10947 *expected = AstType::Union(expected_number, AstType::Number(), zone()); |
| 10953 return value; | 10948 return value; |
| 10954 } | 10949 } |
| 10955 | 10950 |
| 10956 return value; | 10951 return value; |
| 10957 } | 10952 } |
| 10958 | 10953 |
| 10959 | 10954 |
| 10960 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( | 10955 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( |
| 10961 BinaryOperation* expr, | 10956 BinaryOperation* expr, |
| 10962 HValue* left, | 10957 HValue* left, |
| 10963 HValue* right, | 10958 HValue* right, |
| 10964 PushBeforeSimulateBehavior push_sim_result) { | 10959 PushBeforeSimulateBehavior push_sim_result) { |
| 10965 Type* left_type = bounds_.get(expr->left()).lower; | 10960 AstType* left_type = bounds_.get(expr->left()).lower; |
| 10966 Type* right_type = bounds_.get(expr->right()).lower; | 10961 AstType* right_type = bounds_.get(expr->right()).lower; |
| 10967 Type* result_type = bounds_.get(expr).lower; | 10962 AstType* result_type = bounds_.get(expr).lower; |
| 10968 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 10963 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
| 10969 Handle<AllocationSite> allocation_site = expr->allocation_site(); | 10964 Handle<AllocationSite> allocation_site = expr->allocation_site(); |
| 10970 | 10965 |
| 10971 HAllocationMode allocation_mode; | 10966 HAllocationMode allocation_mode; |
| 10972 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { | 10967 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { |
| 10973 allocation_mode = HAllocationMode(allocation_site); | 10968 allocation_mode = HAllocationMode(allocation_site); |
| 10974 } | 10969 } |
| 10975 HValue* result = HGraphBuilder::BuildBinaryOperation( | 10970 HValue* result = HGraphBuilder::BuildBinaryOperation( |
| 10976 expr->op(), left, right, left_type, right_type, result_type, | 10971 expr->op(), left, right, left_type, right_type, result_type, |
| 10977 fixed_right_arg, allocation_mode, expr->id()); | 10972 fixed_right_arg, allocation_mode, expr->id()); |
| 10978 // Add a simulate after instructions with observable side effects, and | 10973 // Add a simulate after instructions with observable side effects, and |
| 10979 // after phis, which are the result of BuildBinaryOperation when we | 10974 // after phis, which are the result of BuildBinaryOperation when we |
| 10980 // inlined some complex subgraph. | 10975 // inlined some complex subgraph. |
| 10981 if (result->HasObservableSideEffects() || result->IsPhi()) { | 10976 if (result->HasObservableSideEffects() || result->IsPhi()) { |
| 10982 if (push_sim_result == PUSH_BEFORE_SIMULATE) { | 10977 if (push_sim_result == PUSH_BEFORE_SIMULATE) { |
| 10983 Push(result); | 10978 Push(result); |
| 10984 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10979 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 10985 Drop(1); | 10980 Drop(1); |
| 10986 } else { | 10981 } else { |
| 10987 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10982 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 10988 } | 10983 } |
| 10989 } | 10984 } |
| 10990 return result; | 10985 return result; |
| 10991 } | 10986 } |
| 10992 | 10987 |
| 10993 HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left, | 10988 HValue* HGraphBuilder::BuildBinaryOperation( |
| 10994 HValue* right, Type* left_type, | 10989 Token::Value op, HValue* left, HValue* right, AstType* left_type, |
| 10995 Type* right_type, Type* result_type, | 10990 AstType* right_type, AstType* result_type, Maybe<int> fixed_right_arg, |
| 10996 Maybe<int> fixed_right_arg, | 10991 HAllocationMode allocation_mode, BailoutId opt_id) { |
| 10997 HAllocationMode allocation_mode, | |
| 10998 BailoutId opt_id) { | |
| 10999 bool maybe_string_add = false; | 10992 bool maybe_string_add = false; |
| 11000 if (op == Token::ADD) { | 10993 if (op == Token::ADD) { |
| 11001 // If we are adding constant string with something for which we don't have | 10994 // If we are adding constant string with something for which we don't have |
| 11002 // a feedback yet, assume that it's also going to be a string and don't | 10995 // a feedback yet, assume that it's also going to be a string and don't |
| 11003 // generate deopt instructions. | 10996 // generate deopt instructions. |
| 11004 if (!left_type->IsInhabited() && right->IsConstant() && | 10997 if (!left_type->IsInhabited() && right->IsConstant() && |
| 11005 HConstant::cast(right)->HasStringValue()) { | 10998 HConstant::cast(right)->HasStringValue()) { |
| 11006 left_type = Type::String(); | 10999 left_type = AstType::String(); |
| 11007 } | 11000 } |
| 11008 | 11001 |
| 11009 if (!right_type->IsInhabited() && left->IsConstant() && | 11002 if (!right_type->IsInhabited() && left->IsConstant() && |
| 11010 HConstant::cast(left)->HasStringValue()) { | 11003 HConstant::cast(left)->HasStringValue()) { |
| 11011 right_type = Type::String(); | 11004 right_type = AstType::String(); |
| 11012 } | 11005 } |
| 11013 | 11006 |
| 11014 maybe_string_add = (left_type->Maybe(Type::String()) || | 11007 maybe_string_add = (left_type->Maybe(AstType::String()) || |
| 11015 left_type->Maybe(Type::Receiver()) || | 11008 left_type->Maybe(AstType::Receiver()) || |
| 11016 right_type->Maybe(Type::String()) || | 11009 right_type->Maybe(AstType::String()) || |
| 11017 right_type->Maybe(Type::Receiver())); | 11010 right_type->Maybe(AstType::Receiver())); |
| 11018 } | 11011 } |
| 11019 | 11012 |
| 11020 Representation left_rep = RepresentationFor(left_type); | 11013 Representation left_rep = RepresentationFor(left_type); |
| 11021 Representation right_rep = RepresentationFor(right_type); | 11014 Representation right_rep = RepresentationFor(right_type); |
| 11022 | 11015 |
| 11023 if (!left_type->IsInhabited()) { | 11016 if (!left_type->IsInhabited()) { |
| 11024 Add<HDeoptimize>( | 11017 Add<HDeoptimize>( |
| 11025 DeoptimizeReason::kInsufficientTypeFeedbackForLHSOfBinaryOperation, | 11018 DeoptimizeReason::kInsufficientTypeFeedbackForLHSOfBinaryOperation, |
| 11026 Deoptimizer::SOFT); | 11019 Deoptimizer::SOFT); |
| 11027 left_type = Type::Any(); | 11020 left_type = AstType::Any(); |
| 11028 left_rep = RepresentationFor(left_type); | 11021 left_rep = RepresentationFor(left_type); |
| 11029 maybe_string_add = op == Token::ADD; | 11022 maybe_string_add = op == Token::ADD; |
| 11030 } | 11023 } |
| 11031 | 11024 |
| 11032 if (!right_type->IsInhabited()) { | 11025 if (!right_type->IsInhabited()) { |
| 11033 Add<HDeoptimize>( | 11026 Add<HDeoptimize>( |
| 11034 DeoptimizeReason::kInsufficientTypeFeedbackForRHSOfBinaryOperation, | 11027 DeoptimizeReason::kInsufficientTypeFeedbackForRHSOfBinaryOperation, |
| 11035 Deoptimizer::SOFT); | 11028 Deoptimizer::SOFT); |
| 11036 right_type = Type::Any(); | 11029 right_type = AstType::Any(); |
| 11037 right_rep = RepresentationFor(right_type); | 11030 right_rep = RepresentationFor(right_type); |
| 11038 maybe_string_add = op == Token::ADD; | 11031 maybe_string_add = op == Token::ADD; |
| 11039 } | 11032 } |
| 11040 | 11033 |
| 11041 if (!maybe_string_add) { | 11034 if (!maybe_string_add) { |
| 11042 left = TruncateToNumber(left, &left_type); | 11035 left = TruncateToNumber(left, &left_type); |
| 11043 right = TruncateToNumber(right, &right_type); | 11036 right = TruncateToNumber(right, &right_type); |
| 11044 } | 11037 } |
| 11045 | 11038 |
| 11046 // Special case for string addition here. | 11039 // Special case for string addition here. |
| 11047 if (op == Token::ADD && | 11040 if (op == Token::ADD && |
| 11048 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 11041 (left_type->Is(AstType::String()) || right_type->Is(AstType::String()))) { |
| 11049 // Validate type feedback for left argument. | 11042 // Validate type feedback for left argument. |
| 11050 if (left_type->Is(Type::String())) { | 11043 if (left_type->Is(AstType::String())) { |
| 11051 left = BuildCheckString(left); | 11044 left = BuildCheckString(left); |
| 11052 } | 11045 } |
| 11053 | 11046 |
| 11054 // Validate type feedback for right argument. | 11047 // Validate type feedback for right argument. |
| 11055 if (right_type->Is(Type::String())) { | 11048 if (right_type->Is(AstType::String())) { |
| 11056 right = BuildCheckString(right); | 11049 right = BuildCheckString(right); |
| 11057 } | 11050 } |
| 11058 | 11051 |
| 11059 // Convert left argument as necessary. | 11052 // Convert left argument as necessary. |
| 11060 if (left_type->Is(Type::Number())) { | 11053 if (left_type->Is(AstType::Number())) { |
| 11061 DCHECK(right_type->Is(Type::String())); | 11054 DCHECK(right_type->Is(AstType::String())); |
| 11062 left = BuildNumberToString(left, left_type); | 11055 left = BuildNumberToString(left, left_type); |
| 11063 } else if (!left_type->Is(Type::String())) { | 11056 } else if (!left_type->Is(AstType::String())) { |
| 11064 DCHECK(right_type->Is(Type::String())); | 11057 DCHECK(right_type->Is(AstType::String())); |
| 11065 return AddUncasted<HStringAdd>( | 11058 return AddUncasted<HStringAdd>( |
| 11066 left, right, allocation_mode.GetPretenureMode(), | 11059 left, right, allocation_mode.GetPretenureMode(), |
| 11067 STRING_ADD_CONVERT_LEFT, allocation_mode.feedback_site()); | 11060 STRING_ADD_CONVERT_LEFT, allocation_mode.feedback_site()); |
| 11068 } | 11061 } |
| 11069 | 11062 |
| 11070 // Convert right argument as necessary. | 11063 // Convert right argument as necessary. |
| 11071 if (right_type->Is(Type::Number())) { | 11064 if (right_type->Is(AstType::Number())) { |
| 11072 DCHECK(left_type->Is(Type::String())); | 11065 DCHECK(left_type->Is(AstType::String())); |
| 11073 right = BuildNumberToString(right, right_type); | 11066 right = BuildNumberToString(right, right_type); |
| 11074 } else if (!right_type->Is(Type::String())) { | 11067 } else if (!right_type->Is(AstType::String())) { |
| 11075 DCHECK(left_type->Is(Type::String())); | 11068 DCHECK(left_type->Is(AstType::String())); |
| 11076 return AddUncasted<HStringAdd>( | 11069 return AddUncasted<HStringAdd>( |
| 11077 left, right, allocation_mode.GetPretenureMode(), | 11070 left, right, allocation_mode.GetPretenureMode(), |
| 11078 STRING_ADD_CONVERT_RIGHT, allocation_mode.feedback_site()); | 11071 STRING_ADD_CONVERT_RIGHT, allocation_mode.feedback_site()); |
| 11079 } | 11072 } |
| 11080 | 11073 |
| 11081 // Fast paths for empty constant strings. | 11074 // Fast paths for empty constant strings. |
| 11082 Handle<String> left_string = | 11075 Handle<String> left_string = |
| 11083 left->IsConstant() && HConstant::cast(left)->HasStringValue() | 11076 left->IsConstant() && HConstant::cast(left)->HasStringValue() |
| 11084 ? HConstant::cast(left)->StringValue() | 11077 ? HConstant::cast(left)->StringValue() |
| 11085 : Handle<String>(); | 11078 : Handle<String>(); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11223 } | 11216 } |
| 11224 case Token::DIV: | 11217 case Token::DIV: |
| 11225 instr = AddUncasted<HDiv>(left, right); | 11218 instr = AddUncasted<HDiv>(left, right); |
| 11226 break; | 11219 break; |
| 11227 case Token::BIT_XOR: | 11220 case Token::BIT_XOR: |
| 11228 case Token::BIT_AND: | 11221 case Token::BIT_AND: |
| 11229 instr = AddUncasted<HBitwise>(op, left, right); | 11222 instr = AddUncasted<HBitwise>(op, left, right); |
| 11230 break; | 11223 break; |
| 11231 case Token::BIT_OR: { | 11224 case Token::BIT_OR: { |
| 11232 HValue *operand, *shift_amount; | 11225 HValue *operand, *shift_amount; |
| 11233 if (left_type->Is(Type::Signed32()) && | 11226 if (left_type->Is(AstType::Signed32()) && |
| 11234 right_type->Is(Type::Signed32()) && | 11227 right_type->Is(AstType::Signed32()) && |
| 11235 MatchRotateRight(left, right, &operand, &shift_amount)) { | 11228 MatchRotateRight(left, right, &operand, &shift_amount)) { |
| 11236 instr = AddUncasted<HRor>(operand, shift_amount); | 11229 instr = AddUncasted<HRor>(operand, shift_amount); |
| 11237 } else { | 11230 } else { |
| 11238 instr = AddUncasted<HBitwise>(op, left, right); | 11231 instr = AddUncasted<HBitwise>(op, left, right); |
| 11239 } | 11232 } |
| 11240 break; | 11233 break; |
| 11241 } | 11234 } |
| 11242 case Token::SAR: | 11235 case Token::SAR: |
| 11243 instr = AddUncasted<HSar>(left, right); | 11236 instr = AddUncasted<HSar>(left, right); |
| 11244 break; | 11237 break; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11496 CallRuntime* call = expr->left()->AsCallRuntime(); | 11489 CallRuntime* call = expr->left()->AsCallRuntime(); |
| 11497 DCHECK(call->arguments()->length() == 1); | 11490 DCHECK(call->arguments()->length() == 1); |
| 11498 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 11491 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 11499 HValue* value = Pop(); | 11492 HValue* value = Pop(); |
| 11500 Literal* literal = expr->right()->AsLiteral(); | 11493 Literal* literal = expr->right()->AsLiteral(); |
| 11501 Handle<String> rhs = Handle<String>::cast(literal->value()); | 11494 Handle<String> rhs = Handle<String>::cast(literal->value()); |
| 11502 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); | 11495 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); |
| 11503 return ast_context()->ReturnControl(instr, expr->id()); | 11496 return ast_context()->ReturnControl(instr, expr->id()); |
| 11504 } | 11497 } |
| 11505 | 11498 |
| 11506 Type* left_type = bounds_.get(expr->left()).lower; | 11499 AstType* left_type = bounds_.get(expr->left()).lower; |
| 11507 Type* right_type = bounds_.get(expr->right()).lower; | 11500 AstType* right_type = bounds_.get(expr->right()).lower; |
| 11508 Type* combined_type = expr->combined_type(); | 11501 AstType* combined_type = expr->combined_type(); |
| 11509 | 11502 |
| 11510 CHECK_ALIVE(VisitForValue(expr->left())); | 11503 CHECK_ALIVE(VisitForValue(expr->left())); |
| 11511 CHECK_ALIVE(VisitForValue(expr->right())); | 11504 CHECK_ALIVE(VisitForValue(expr->right())); |
| 11512 | 11505 |
| 11513 HValue* right = Pop(); | 11506 HValue* right = Pop(); |
| 11514 HValue* left = Pop(); | 11507 HValue* left = Pop(); |
| 11515 Token::Value op = expr->op(); | 11508 Token::Value op = expr->op(); |
| 11516 | 11509 |
| 11517 if (IsLiteralCompareStrict(isolate(), left, op, right)) { | 11510 if (IsLiteralCompareStrict(isolate(), left, op, right)) { |
| 11518 HCompareObjectEqAndBranch* result = | 11511 HCompareObjectEqAndBranch* result = |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11570 : PUSH_BEFORE_SIMULATE; | 11563 : PUSH_BEFORE_SIMULATE; |
| 11571 HControlInstruction* compare = BuildCompareInstruction( | 11564 HControlInstruction* compare = BuildCompareInstruction( |
| 11572 op, left, right, left_type, right_type, combined_type, | 11565 op, left, right, left_type, right_type, combined_type, |
| 11573 ScriptPositionToSourcePosition(expr->left()->position()), | 11566 ScriptPositionToSourcePosition(expr->left()->position()), |
| 11574 ScriptPositionToSourcePosition(expr->right()->position()), | 11567 ScriptPositionToSourcePosition(expr->right()->position()), |
| 11575 push_behavior, expr->id()); | 11568 push_behavior, expr->id()); |
| 11576 if (compare == NULL) return; // Bailed out. | 11569 if (compare == NULL) return; // Bailed out. |
| 11577 return ast_context()->ReturnControl(compare, expr->id()); | 11570 return ast_context()->ReturnControl(compare, expr->id()); |
| 11578 } | 11571 } |
| 11579 | 11572 |
| 11580 | |
| 11581 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( | 11573 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( |
| 11582 Token::Value op, HValue* left, HValue* right, Type* left_type, | 11574 Token::Value op, HValue* left, HValue* right, AstType* left_type, |
| 11583 Type* right_type, Type* combined_type, SourcePosition left_position, | 11575 AstType* right_type, AstType* combined_type, SourcePosition left_position, |
| 11584 SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, | 11576 SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, |
| 11585 BailoutId bailout_id) { | 11577 BailoutId bailout_id) { |
| 11586 // Cases handled below depend on collected type feedback. They should | 11578 // Cases handled below depend on collected type feedback. They should |
| 11587 // soft deoptimize when there is no type feedback. | 11579 // soft deoptimize when there is no type feedback. |
| 11588 if (!combined_type->IsInhabited()) { | 11580 if (!combined_type->IsInhabited()) { |
| 11589 Add<HDeoptimize>( | 11581 Add<HDeoptimize>( |
| 11590 DeoptimizeReason:: | 11582 DeoptimizeReason:: |
| 11591 kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, | 11583 kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, |
| 11592 Deoptimizer::SOFT); | 11584 Deoptimizer::SOFT); |
| 11593 combined_type = left_type = right_type = Type::Any(); | 11585 combined_type = left_type = right_type = AstType::Any(); |
| 11594 } | 11586 } |
| 11595 | 11587 |
| 11596 Representation left_rep = RepresentationFor(left_type); | 11588 Representation left_rep = RepresentationFor(left_type); |
| 11597 Representation right_rep = RepresentationFor(right_type); | 11589 Representation right_rep = RepresentationFor(right_type); |
| 11598 Representation combined_rep = RepresentationFor(combined_type); | 11590 Representation combined_rep = RepresentationFor(combined_type); |
| 11599 | 11591 |
| 11600 if (combined_type->Is(Type::Receiver())) { | 11592 if (combined_type->Is(AstType::Receiver())) { |
| 11601 if (Token::IsEqualityOp(op)) { | 11593 if (Token::IsEqualityOp(op)) { |
| 11602 // HCompareObjectEqAndBranch can only deal with object, so | 11594 // HCompareObjectEqAndBranch can only deal with object, so |
| 11603 // exclude numbers. | 11595 // exclude numbers. |
| 11604 if ((left->IsConstant() && | 11596 if ((left->IsConstant() && |
| 11605 HConstant::cast(left)->HasNumberValue()) || | 11597 HConstant::cast(left)->HasNumberValue()) || |
| 11606 (right->IsConstant() && | 11598 (right->IsConstant() && |
| 11607 HConstant::cast(right)->HasNumberValue())) { | 11599 HConstant::cast(right)->HasNumberValue())) { |
| 11608 Add<HDeoptimize>( | 11600 Add<HDeoptimize>( |
| 11609 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, | 11601 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, |
| 11610 Deoptimizer::SOFT); | 11602 Deoptimizer::SOFT); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11674 AddCheckMap(left, map); | 11666 AddCheckMap(left, map); |
| 11675 AddCheckMap(right, map); | 11667 AddCheckMap(right, map); |
| 11676 // The caller expects a branch instruction, so make it happy. | 11668 // The caller expects a branch instruction, so make it happy. |
| 11677 return New<HBranch>( | 11669 return New<HBranch>( |
| 11678 graph()->GetConstantBool(op == Token::LTE || op == Token::GTE)); | 11670 graph()->GetConstantBool(op == Token::LTE || op == Token::GTE)); |
| 11679 } | 11671 } |
| 11680 } | 11672 } |
| 11681 Bailout(kUnsupportedNonPrimitiveCompare); | 11673 Bailout(kUnsupportedNonPrimitiveCompare); |
| 11682 return NULL; | 11674 return NULL; |
| 11683 } | 11675 } |
| 11684 } else if (combined_type->Is(Type::InternalizedString()) && | 11676 } else if (combined_type->Is(AstType::InternalizedString()) && |
| 11685 Token::IsEqualityOp(op)) { | 11677 Token::IsEqualityOp(op)) { |
| 11686 // If we have a constant argument, it should be consistent with the type | 11678 // If we have a constant argument, it should be consistent with the type |
| 11687 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). | 11679 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). |
| 11688 if ((left->IsConstant() && | 11680 if ((left->IsConstant() && |
| 11689 !HConstant::cast(left)->HasInternalizedStringValue()) || | 11681 !HConstant::cast(left)->HasInternalizedStringValue()) || |
| 11690 (right->IsConstant() && | 11682 (right->IsConstant() && |
| 11691 !HConstant::cast(right)->HasInternalizedStringValue())) { | 11683 !HConstant::cast(right)->HasInternalizedStringValue())) { |
| 11692 Add<HDeoptimize>( | 11684 Add<HDeoptimize>( |
| 11693 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, | 11685 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, |
| 11694 Deoptimizer::SOFT); | 11686 Deoptimizer::SOFT); |
| 11695 // The caller expects a branch instruction, so make it happy. | 11687 // The caller expects a branch instruction, so make it happy. |
| 11696 return New<HBranch>(graph()->GetConstantTrue()); | 11688 return New<HBranch>(graph()->GetConstantTrue()); |
| 11697 } | 11689 } |
| 11698 BuildCheckHeapObject(left); | 11690 BuildCheckHeapObject(left); |
| 11699 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); | 11691 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); |
| 11700 BuildCheckHeapObject(right); | 11692 BuildCheckHeapObject(right); |
| 11701 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); | 11693 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); |
| 11702 HCompareObjectEqAndBranch* result = | 11694 HCompareObjectEqAndBranch* result = |
| 11703 New<HCompareObjectEqAndBranch>(left, right); | 11695 New<HCompareObjectEqAndBranch>(left, right); |
| 11704 return result; | 11696 return result; |
| 11705 } else if (combined_type->Is(Type::String())) { | 11697 } else if (combined_type->Is(AstType::String())) { |
| 11706 BuildCheckHeapObject(left); | 11698 BuildCheckHeapObject(left); |
| 11707 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); | 11699 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); |
| 11708 BuildCheckHeapObject(right); | 11700 BuildCheckHeapObject(right); |
| 11709 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); | 11701 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); |
| 11710 HStringCompareAndBranch* result = | 11702 HStringCompareAndBranch* result = |
| 11711 New<HStringCompareAndBranch>(left, right, op); | 11703 New<HStringCompareAndBranch>(left, right, op); |
| 11712 return result; | 11704 return result; |
| 11713 } else if (combined_type->Is(Type::Boolean())) { | 11705 } else if (combined_type->Is(AstType::Boolean())) { |
| 11714 AddCheckMap(left, isolate()->factory()->boolean_map()); | 11706 AddCheckMap(left, isolate()->factory()->boolean_map()); |
| 11715 AddCheckMap(right, isolate()->factory()->boolean_map()); | 11707 AddCheckMap(right, isolate()->factory()->boolean_map()); |
| 11716 if (Token::IsEqualityOp(op)) { | 11708 if (Token::IsEqualityOp(op)) { |
| 11717 HCompareObjectEqAndBranch* result = | 11709 HCompareObjectEqAndBranch* result = |
| 11718 New<HCompareObjectEqAndBranch>(left, right); | 11710 New<HCompareObjectEqAndBranch>(left, right); |
| 11719 return result; | 11711 return result; |
| 11720 } | 11712 } |
| 11721 left = Add<HLoadNamedField>( | 11713 left = Add<HLoadNamedField>( |
| 11722 left, nullptr, | 11714 left, nullptr, |
| 11723 HObjectAccess::ForOddballToNumber(Representation::Smi())); | 11715 HObjectAccess::ForOddballToNumber(Representation::Smi())); |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12508 HValue* result = BuildRegExpConstructResult(length, index, input); | 12500 HValue* result = BuildRegExpConstructResult(length, index, input); |
| 12509 return ast_context()->ReturnValue(result); | 12501 return ast_context()->ReturnValue(result); |
| 12510 } | 12502 } |
| 12511 | 12503 |
| 12512 | 12504 |
| 12513 // Fast support for number to string. | 12505 // Fast support for number to string. |
| 12514 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { | 12506 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
| 12515 DCHECK_EQ(1, call->arguments()->length()); | 12507 DCHECK_EQ(1, call->arguments()->length()); |
| 12516 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12508 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12517 HValue* number = Pop(); | 12509 HValue* number = Pop(); |
| 12518 HValue* result = BuildNumberToString(number, Type::Any()); | 12510 HValue* result = BuildNumberToString(number, AstType::Any()); |
| 12519 return ast_context()->ReturnValue(result); | 12511 return ast_context()->ReturnValue(result); |
| 12520 } | 12512 } |
| 12521 | 12513 |
| 12522 | 12514 |
| 12523 // Fast support for calls. | 12515 // Fast support for calls. |
| 12524 void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { | 12516 void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { |
| 12525 DCHECK_LE(2, call->arguments()->length()); | 12517 DCHECK_LE(2, call->arguments()->length()); |
| 12526 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12518 CHECK_ALIVE(VisitExpressions(call->arguments())); |
| 12527 CallTrampolineDescriptor descriptor(isolate()); | 12519 CallTrampolineDescriptor descriptor(isolate()); |
| 12528 PushArgumentsFromEnvironment(call->arguments()->length() - 1); | 12520 PushArgumentsFromEnvironment(call->arguments()->length() - 1); |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13402 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13394 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13403 } | 13395 } |
| 13404 | 13396 |
| 13405 #ifdef DEBUG | 13397 #ifdef DEBUG |
| 13406 graph_->Verify(false); // No full verify. | 13398 graph_->Verify(false); // No full verify. |
| 13407 #endif | 13399 #endif |
| 13408 } | 13400 } |
| 13409 | 13401 |
| 13410 } // namespace internal | 13402 } // namespace internal |
| 13411 } // namespace v8 | 13403 } // namespace v8 |
| OLD | NEW |