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 |
3183 void HGraphBuilder::BuildCreateAllocationMemento( | 3235 void HGraphBuilder::BuildCreateAllocationMemento( |
3184 HValue* previous_object, | 3236 HValue* previous_object, |
3185 HValue* previous_object_size, | 3237 HValue* previous_object_size, |
3186 HValue* allocation_site) { | 3238 HValue* allocation_site) { |
3187 DCHECK(allocation_site != NULL); | 3239 DCHECK(allocation_site != NULL); |
3188 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( | 3240 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( |
3189 previous_object, previous_object_size, HType::HeapObject()); | 3241 previous_object, previous_object_size, HType::HeapObject()); |
3190 AddStoreMapConstant( | 3242 AddStoreMapConstant( |
3191 allocation_memento, isolate()->factory()->allocation_memento_map()); | 3243 allocation_memento, isolate()->factory()->allocation_memento_map()); |
3192 Add<HStoreNamedField>( | 3244 Add<HStoreNamedField>( |
(...skipping 8488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11681 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 11733 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
11682 Expression* sub_expr, | 11734 Expression* sub_expr, |
11683 NilValue nil) { | 11735 NilValue nil) { |
11684 DCHECK(!HasStackOverflow()); | 11736 DCHECK(!HasStackOverflow()); |
11685 DCHECK(current_block() != NULL); | 11737 DCHECK(current_block() != NULL); |
11686 DCHECK(current_block()->HasPredecessor()); | 11738 DCHECK(current_block()->HasPredecessor()); |
11687 DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); | 11739 DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); |
11688 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); | 11740 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); |
11689 CHECK_ALIVE(VisitForValue(sub_expr)); | 11741 CHECK_ALIVE(VisitForValue(sub_expr)); |
11690 HValue* value = Pop(); | 11742 HValue* value = Pop(); |
11691 HControlInstruction* instr; | |
11692 if (expr->op() == Token::EQ_STRICT) { | 11743 if (expr->op() == Token::EQ_STRICT) { |
11693 HConstant* nil_constant = nil == kNullValue | 11744 HConstant* nil_constant = nil == kNullValue |
11694 ? graph()->GetConstantNull() | 11745 ? graph()->GetConstantNull() |
11695 : graph()->GetConstantUndefined(); | 11746 : graph()->GetConstantUndefined(); |
11696 instr = New<HCompareObjectEqAndBranch>(value, nil_constant); | 11747 HCompareObjectEqAndBranch* instr = |
| 11748 New<HCompareObjectEqAndBranch>(value, nil_constant); |
| 11749 return ast_context()->ReturnControl(instr, expr->id()); |
11697 } else { | 11750 } else { |
11698 DCHECK_EQ(Token::EQ, expr->op()); | 11751 DCHECK_EQ(Token::EQ, expr->op()); |
11699 instr = New<HIsUndetectableAndBranch>(value); | 11752 Type* type = expr->combined_type()->Is(Type::None()) |
| 11753 ? Type::Any() |
| 11754 : expr->combined_type(); |
| 11755 HIfContinuation continuation; |
| 11756 BuildCompareNil(value, type, &continuation); |
| 11757 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
11700 } | 11758 } |
11701 return ast_context()->ReturnControl(instr, expr->id()); | |
11702 } | 11759 } |
11703 | 11760 |
11704 | 11761 |
11705 void HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } | 11762 void HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } |
11706 | 11763 |
11707 | 11764 |
11708 void HOptimizedGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { | 11765 void HOptimizedGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { |
11709 UNREACHABLE(); | 11766 UNREACHABLE(); |
11710 } | 11767 } |
11711 | 11768 |
(...skipping 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13468 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13525 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13469 } | 13526 } |
13470 | 13527 |
13471 #ifdef DEBUG | 13528 #ifdef DEBUG |
13472 graph_->Verify(false); // No full verify. | 13529 graph_->Verify(false); // No full verify. |
13473 #endif | 13530 #endif |
13474 } | 13531 } |
13475 | 13532 |
13476 } // namespace internal | 13533 } // namespace internal |
13477 } // namespace v8 | 13534 } // namespace v8 |
OLD | NEW |