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 |