| 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 <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 3162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3173 // And the result of the length | 3173 // And the result of the length |
| 3174 HValue* length = AddLoadArrayLength(boilerplate, kind); | 3174 HValue* length = AddLoadArrayLength(boilerplate, kind); |
| 3175 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length); | 3175 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length); |
| 3176 | 3176 |
| 3177 BuildCopyElements(boilerplate_elements, kind, elements, | 3177 BuildCopyElements(boilerplate_elements, kind, elements, |
| 3178 kind, length, NULL); | 3178 kind, length, NULL); |
| 3179 return result; | 3179 return result; |
| 3180 } | 3180 } |
| 3181 | 3181 |
| 3182 | 3182 |
| 3183 void HGraphBuilder::BuildCompareNil(HValue* value, Type* type, | |
| 3184 HIfContinuation* continuation, | |
| 3185 MapEmbedding map_embedding) { | |
| 3186 IfBuilder if_nil(this); | |
| 3187 | |
| 3188 if (type->Maybe(Type::Undetectable())) { | |
| 3189 if_nil.If<HIsUndetectableAndBranch>(value); | |
| 3190 } else { | |
| 3191 bool maybe_null = type->Maybe(Type::Null()); | |
| 3192 if (maybe_null) { | |
| 3193 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); | |
| 3194 } | |
| 3195 | |
| 3196 if (type->Maybe(Type::Undefined())) { | |
| 3197 if (maybe_null) if_nil.Or(); | |
| 3198 if_nil.If<HCompareObjectEqAndBranch>(value, | |
| 3199 graph()->GetConstantUndefined()); | |
| 3200 } | |
| 3201 | |
| 3202 if_nil.Then(); | |
| 3203 if_nil.Else(); | |
| 3204 | |
| 3205 if (type->NumClasses() == 1) { | |
| 3206 BuildCheckHeapObject(value); | |
| 3207 // For ICs, the map checked below is a sentinel map that gets replaced by | |
| 3208 // the monomorphic map when the code is used as a template to generate a | |
| 3209 // new IC. For optimized functions, there is no sentinel map, the map | |
| 3210 // emitted below is the actual monomorphic map. | |
| 3211 if (map_embedding == kEmbedMapsViaWeakCells) { | |
| 3212 HValue* cell = | |
| 3213 Add<HConstant>(Map::WeakCellForMap(type->Classes().Current())); | |
| 3214 HValue* expected_map = Add<HLoadNamedField>( | |
| 3215 cell, nullptr, HObjectAccess::ForWeakCellValue()); | |
| 3216 HValue* map = | |
| 3217 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap()); | |
| 3218 IfBuilder map_check(this); | |
| 3219 map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map); | |
| 3220 map_check.ThenDeopt(Deoptimizer::kUnknownMap); | |
| 3221 map_check.End(); | |
| 3222 } else { | |
| 3223 DCHECK(map_embedding == kEmbedMapsDirectly); | |
| 3224 Add<HCheckMaps>(value, type->Classes().Current()); | |
| 3225 } | |
| 3226 } else { | |
| 3227 if_nil.Deopt(Deoptimizer::kTooManyUndetectableTypes); | |
| 3228 } | |
| 3229 } | |
| 3230 | |
| 3231 if_nil.CaptureContinuation(continuation); | |
| 3232 } | |
| 3233 | |
| 3234 | |
| 3235 void HGraphBuilder::BuildCreateAllocationMemento( | 3183 void HGraphBuilder::BuildCreateAllocationMemento( |
| 3236 HValue* previous_object, | 3184 HValue* previous_object, |
| 3237 HValue* previous_object_size, | 3185 HValue* previous_object_size, |
| 3238 HValue* allocation_site) { | 3186 HValue* allocation_site) { |
| 3239 DCHECK(allocation_site != NULL); | 3187 DCHECK(allocation_site != NULL); |
| 3240 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( | 3188 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( |
| 3241 previous_object, previous_object_size, HType::HeapObject()); | 3189 previous_object, previous_object_size, HType::HeapObject()); |
| 3242 AddStoreMapConstant( | 3190 AddStoreMapConstant( |
| 3243 allocation_memento, isolate()->factory()->allocation_memento_map()); | 3191 allocation_memento, isolate()->factory()->allocation_memento_map()); |
| 3244 Add<HStoreNamedField>( | 3192 Add<HStoreNamedField>( |
| (...skipping 8473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11718 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 11666 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 11719 Expression* sub_expr, | 11667 Expression* sub_expr, |
| 11720 NilValue nil) { | 11668 NilValue nil) { |
| 11721 DCHECK(!HasStackOverflow()); | 11669 DCHECK(!HasStackOverflow()); |
| 11722 DCHECK(current_block() != NULL); | 11670 DCHECK(current_block() != NULL); |
| 11723 DCHECK(current_block()->HasPredecessor()); | 11671 DCHECK(current_block()->HasPredecessor()); |
| 11724 DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); | 11672 DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); |
| 11725 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); | 11673 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); |
| 11726 CHECK_ALIVE(VisitForValue(sub_expr)); | 11674 CHECK_ALIVE(VisitForValue(sub_expr)); |
| 11727 HValue* value = Pop(); | 11675 HValue* value = Pop(); |
| 11676 HControlInstruction* instr; |
| 11728 if (expr->op() == Token::EQ_STRICT) { | 11677 if (expr->op() == Token::EQ_STRICT) { |
| 11729 HConstant* nil_constant = nil == kNullValue | 11678 HConstant* nil_constant = nil == kNullValue |
| 11730 ? graph()->GetConstantNull() | 11679 ? graph()->GetConstantNull() |
| 11731 : graph()->GetConstantUndefined(); | 11680 : graph()->GetConstantUndefined(); |
| 11732 HCompareObjectEqAndBranch* instr = | 11681 instr = New<HCompareObjectEqAndBranch>(value, nil_constant); |
| 11733 New<HCompareObjectEqAndBranch>(value, nil_constant); | |
| 11734 return ast_context()->ReturnControl(instr, expr->id()); | |
| 11735 } else { | 11682 } else { |
| 11736 DCHECK_EQ(Token::EQ, expr->op()); | 11683 DCHECK_EQ(Token::EQ, expr->op()); |
| 11737 Type* type = expr->combined_type()->Is(Type::None()) | 11684 instr = New<HIsUndetectableAndBranch>(value); |
| 11738 ? Type::Any() | |
| 11739 : expr->combined_type(); | |
| 11740 HIfContinuation continuation; | |
| 11741 BuildCompareNil(value, type, &continuation); | |
| 11742 return ast_context()->ReturnContinuation(&continuation, expr->id()); | |
| 11743 } | 11685 } |
| 11686 return ast_context()->ReturnControl(instr, expr->id()); |
| 11744 } | 11687 } |
| 11745 | 11688 |
| 11746 | 11689 |
| 11747 void HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } | 11690 void HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } |
| 11748 | 11691 |
| 11749 | 11692 |
| 11750 void HOptimizedGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { | 11693 void HOptimizedGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { |
| 11751 UNREACHABLE(); | 11694 UNREACHABLE(); |
| 11752 } | 11695 } |
| 11753 | 11696 |
| (...skipping 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13510 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13453 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13511 } | 13454 } |
| 13512 | 13455 |
| 13513 #ifdef DEBUG | 13456 #ifdef DEBUG |
| 13514 graph_->Verify(false); // No full verify. | 13457 graph_->Verify(false); // No full verify. |
| 13515 #endif | 13458 #endif |
| 13516 } | 13459 } |
| 13517 | 13460 |
| 13518 } // namespace internal | 13461 } // namespace internal |
| 13519 } // namespace v8 | 13462 } // namespace v8 |
| OLD | NEW |