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 |