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

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 2302283002: Forking the type system between Crankshaft & Turbofan. (Closed)
Patch Set: Nits. Created 4 years, 3 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/crankshaft/hydrogen.h ('k') | src/crankshaft/hydrogen-types.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/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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/crankshaft/hydrogen-types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698