| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1806 | 1806 |
| 1807 current = current->EnsureAndPropagateNotMinusZero(visited); | 1807 current = current->EnsureAndPropagateNotMinusZero(visited); |
| 1808 } | 1808 } |
| 1809 } | 1809 } |
| 1810 | 1810 |
| 1811 | 1811 |
| 1812 void HGraph::InsertRepresentationChangeForUse(HValue* value, | 1812 void HGraph::InsertRepresentationChangeForUse(HValue* value, |
| 1813 HValue* use, | 1813 HValue* use, |
| 1814 Representation to, | 1814 Representation to, |
| 1815 bool is_truncating) { | 1815 bool is_truncating) { |
| 1816 // Propagate flags for negative zero checks upwards from conversions | |
| 1817 // int32-to-tagged and int32-to-double. | |
| 1818 Representation from = value->representation(); | |
| 1819 if (from.IsInteger32()) { | |
| 1820 ASSERT(to.IsTagged() || to.IsDouble()); | |
| 1821 BitVector visited(GetMaximumValueID()); | |
| 1822 PropagateMinusZeroChecks(value, &visited); | |
| 1823 } | |
| 1824 | |
| 1825 // Insert the representation change right before its use. For phi-uses we | 1816 // Insert the representation change right before its use. For phi-uses we |
| 1826 // insert at the end of the corresponding predecessor. | 1817 // insert at the end of the corresponding predecessor. |
| 1827 HBasicBlock* insert_block = use->block(); | 1818 HBasicBlock* insert_block = use->block(); |
| 1828 if (use->IsPhi()) { | 1819 if (use->IsPhi()) { |
| 1829 int index = 0; | 1820 int index = 0; |
| 1830 while (use->OperandAt(index) != value) ++index; | 1821 while (use->OperandAt(index) != value) ++index; |
| 1831 insert_block = insert_block->predecessors()->at(index); | 1822 insert_block = insert_block->predecessors()->at(index); |
| 1832 } | 1823 } |
| 1833 | 1824 |
| 1834 HInstruction* next = (insert_block == use->block()) | 1825 HInstruction* next = (insert_block == use->block()) |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1977 // Process normal instructions. | 1968 // Process normal instructions. |
| 1978 HInstruction* current = blocks_[i]->first(); | 1969 HInstruction* current = blocks_[i]->first(); |
| 1979 while (current != NULL) { | 1970 while (current != NULL) { |
| 1980 InsertRepresentationChanges(current); | 1971 InsertRepresentationChanges(current); |
| 1981 current = current->next(); | 1972 current = current->next(); |
| 1982 } | 1973 } |
| 1983 } | 1974 } |
| 1984 } | 1975 } |
| 1985 | 1976 |
| 1986 | 1977 |
| 1978 void HGraph::ComputeMinusZeroChecks() { |
| 1979 BitVector visited(GetMaximumValueID()); |
| 1980 for (int i = 0; i < blocks_.length(); ++i) { |
| 1981 for (HInstruction* current = blocks_[i]->first(); |
| 1982 current != NULL; |
| 1983 current = current->next()) { |
| 1984 if (current->IsChange()) { |
| 1985 HChange* change = HChange::cast(current); |
| 1986 // Propagate flags for negative zero checks upwards from conversions |
| 1987 // int32-to-tagged and int32-to-double. |
| 1988 Representation from = change->value()->representation(); |
| 1989 ASSERT(from.Equals(change->from())); |
| 1990 if (from.IsInteger32()) { |
| 1991 ASSERT(change->to().IsTagged() || change->to().IsDouble()); |
| 1992 ASSERT(visited.IsEmpty()); |
| 1993 PropagateMinusZeroChecks(change->value(), &visited); |
| 1994 visited.Clear(); |
| 1995 } |
| 1996 } |
| 1997 } |
| 1998 } |
| 1999 } |
| 2000 |
| 2001 |
| 1987 // Implementation of utility classes to represent an expression's context in | 2002 // Implementation of utility classes to represent an expression's context in |
| 1988 // the AST. | 2003 // the AST. |
| 1989 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) | 2004 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) |
| 1990 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { | 2005 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { |
| 1991 owner->set_ast_context(this); // Push. | 2006 owner->set_ast_context(this); // Push. |
| 1992 #ifdef DEBUG | 2007 #ifdef DEBUG |
| 1993 original_length_ = owner->environment()->length(); | 2008 original_length_ = owner->environment()->length(); |
| 1994 #endif | 2009 #endif |
| 1995 } | 2010 } |
| 1996 | 2011 |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 rep.Analyze(); | 2251 rep.Analyze(); |
| 2237 | 2252 |
| 2238 if (FLAG_use_range) { | 2253 if (FLAG_use_range) { |
| 2239 HRangeAnalysis rangeAnalysis(graph_); | 2254 HRangeAnalysis rangeAnalysis(graph_); |
| 2240 rangeAnalysis.Analyze(); | 2255 rangeAnalysis.Analyze(); |
| 2241 } | 2256 } |
| 2242 | 2257 |
| 2243 graph_->InitializeInferredTypes(); | 2258 graph_->InitializeInferredTypes(); |
| 2244 graph_->Canonicalize(); | 2259 graph_->Canonicalize(); |
| 2245 graph_->InsertRepresentationChanges(); | 2260 graph_->InsertRepresentationChanges(); |
| 2261 graph_->ComputeMinusZeroChecks(); |
| 2246 | 2262 |
| 2247 // Eliminate redundant stack checks on backwards branches. | 2263 // Eliminate redundant stack checks on backwards branches. |
| 2248 HStackCheckEliminator sce(graph_); | 2264 HStackCheckEliminator sce(graph_); |
| 2249 sce.Process(); | 2265 sce.Process(); |
| 2250 | 2266 |
| 2251 // Perform common subexpression elimination and loop-invariant code motion. | 2267 // Perform common subexpression elimination and loop-invariant code motion. |
| 2252 if (FLAG_use_gvn) { | 2268 if (FLAG_use_gvn) { |
| 2253 HPhase phase("Global value numbering", graph_); | 2269 HPhase phase("Global value numbering", graph_); |
| 2254 HGlobalValueNumberer gvn(graph_); | 2270 HGlobalValueNumberer gvn(graph_); |
| 2255 gvn.Analyze(); | 2271 gvn.Analyze(); |
| (...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3363 // superclass of Assignment and CountOperation, we cannot just pass the | 3379 // superclass of Assignment and CountOperation, we cannot just pass the |
| 3364 // owning expression instead of position and ast_id separately. | 3380 // owning expression instead of position and ast_id separately. |
| 3365 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3381 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| 3366 HValue* value, | 3382 HValue* value, |
| 3367 int position, | 3383 int position, |
| 3368 int ast_id) { | 3384 int ast_id) { |
| 3369 LookupResult lookup; | 3385 LookupResult lookup; |
| 3370 LookupGlobalPropertyCell(var, &lookup, true); | 3386 LookupGlobalPropertyCell(var, &lookup, true); |
| 3371 CHECK_BAILOUT; | 3387 CHECK_BAILOUT; |
| 3372 | 3388 |
| 3389 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| 3373 Handle<GlobalObject> global(graph()->info()->global_object()); | 3390 Handle<GlobalObject> global(graph()->info()->global_object()); |
| 3374 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3391 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 3375 HInstruction* instr = new HStoreGlobal(value, cell); | 3392 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); |
| 3376 instr->set_position(position); | 3393 instr->set_position(position); |
| 3377 AddInstruction(instr); | 3394 AddInstruction(instr); |
| 3378 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3395 if (instr->HasSideEffects()) AddSimulate(ast_id); |
| 3379 } | 3396 } |
| 3380 | 3397 |
| 3381 | 3398 |
| 3382 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 3399 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 3383 Expression* target = expr->target(); | 3400 Expression* target = expr->target(); |
| 3384 VariableProxy* proxy = target->AsVariableProxy(); | 3401 VariableProxy* proxy = target->AsVariableProxy(); |
| 3385 Variable* var = proxy->AsVariable(); | 3402 Variable* var = proxy->AsVariable(); |
| 3386 Property* prop = target->AsProperty(); | 3403 Property* prop = target->AsProperty(); |
| 3387 ASSERT(var == NULL || prop == NULL); | 3404 ASSERT(var == NULL || prop == NULL); |
| 3388 | 3405 |
| 3389 // We have a second position recorded in the FullCodeGenerator to have | 3406 // We have a second position recorded in the FullCodeGenerator to have |
| 3390 // type feedback for the binary operation. | 3407 // type feedback for the binary operation. |
| 3391 BinaryOperation* operation = expr->binary_operation(); | 3408 BinaryOperation* operation = expr->binary_operation(); |
| 3392 operation->RecordTypeFeedback(oracle()); | |
| 3393 | 3409 |
| 3394 if (var != NULL) { | 3410 if (var != NULL) { |
| 3395 if (!var->is_global() && !var->IsStackAllocated()) { | 3411 if (!var->is_global() && !var->IsStackAllocated()) { |
| 3396 BAILOUT("non-stack/non-global in compound assignment"); | 3412 BAILOUT("non-stack/non-global in compound assignment"); |
| 3397 } | 3413 } |
| 3398 | 3414 |
| 3399 VISIT_FOR_VALUE(operation); | 3415 VISIT_FOR_VALUE(operation); |
| 3400 | 3416 |
| 3401 if (var->is_global()) { | 3417 if (var->is_global()) { |
| 3402 HandleGlobalVariableAssignment(var, | 3418 HandleGlobalVariableAssignment(var, |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3533 | 3549 |
| 3534 | 3550 |
| 3535 void HGraphBuilder::VisitThrow(Throw* expr) { | 3551 void HGraphBuilder::VisitThrow(Throw* expr) { |
| 3536 // We don't optimize functions with invalid left-hand sides in | 3552 // We don't optimize functions with invalid left-hand sides in |
| 3537 // assignments, count operations, or for-in. Consequently throw can | 3553 // assignments, count operations, or for-in. Consequently throw can |
| 3538 // currently only occur in an effect context. | 3554 // currently only occur in an effect context. |
| 3539 ASSERT(ast_context()->IsEffect()); | 3555 ASSERT(ast_context()->IsEffect()); |
| 3540 VISIT_FOR_VALUE(expr->exception()); | 3556 VISIT_FOR_VALUE(expr->exception()); |
| 3541 | 3557 |
| 3542 HValue* value = environment()->Pop(); | 3558 HValue* value = environment()->Pop(); |
| 3543 HControlInstruction* instr = new HThrow(value); | 3559 HThrow* instr = new HThrow(value); |
| 3544 instr->set_position(expr->position()); | 3560 instr->set_position(expr->position()); |
| 3545 current_subgraph_->FinishExit(instr); | 3561 AddInstruction(instr); |
| 3562 AddSimulate(expr->id()); |
| 3563 current_subgraph_->FinishExit(new HAbnormalExit); |
| 3546 } | 3564 } |
| 3547 | 3565 |
| 3548 | 3566 |
| 3549 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 3567 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| 3550 HValue* object, | 3568 HValue* object, |
| 3551 ZoneMapList* types, | 3569 ZoneMapList* types, |
| 3552 Handle<String> name) { | 3570 Handle<String> name) { |
| 3553 int number_of_types = Min(types->length(), kMaxLoadPolymorphism); | 3571 int number_of_types = Min(types->length(), kMaxLoadPolymorphism); |
| 3554 ZoneMapList maps(number_of_types); | 3572 ZoneMapList maps(number_of_types); |
| 3555 ZoneList<HSubgraph*> subgraphs(number_of_types + 1); | 3573 ZoneList<HSubgraph*> subgraphs(number_of_types + 1); |
| (...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4806 break; | 4824 break; |
| 4807 case Token::SHR: | 4825 case Token::SHR: |
| 4808 instr = new HShr(left, right); | 4826 instr = new HShr(left, right); |
| 4809 break; | 4827 break; |
| 4810 case Token::SHL: | 4828 case Token::SHL: |
| 4811 instr = new HShl(left, right); | 4829 instr = new HShl(left, right); |
| 4812 break; | 4830 break; |
| 4813 default: | 4831 default: |
| 4814 UNREACHABLE(); | 4832 UNREACHABLE(); |
| 4815 } | 4833 } |
| 4816 TypeInfo info = oracle()->BinaryType(expr, TypeFeedbackOracle::RESULT); | 4834 TypeInfo info = oracle()->BinaryType(expr); |
| 4817 // If we hit an uninitialized binary op stub we will get type info | 4835 // If we hit an uninitialized binary op stub we will get type info |
| 4818 // for a smi operation. If one of the operands is a constant string | 4836 // for a smi operation. If one of the operands is a constant string |
| 4819 // do not generate code assuming it is a smi operation. | 4837 // do not generate code assuming it is a smi operation. |
| 4820 if (info.IsSmi() && | 4838 if (info.IsSmi() && |
| 4821 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || | 4839 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || |
| 4822 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) { | 4840 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) { |
| 4823 return instr; | 4841 return instr; |
| 4824 } | 4842 } |
| 4825 if (FLAG_trace_representation) { | 4843 if (FLAG_trace_representation) { |
| 4826 PrintF("Info: %s/%s\n", info.ToString(), ToRepresentation(info).Mnemonic()); | 4844 PrintF("Info: %s/%s\n", info.ToString(), ToRepresentation(info).Mnemonic()); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4957 return; | 4975 return; |
| 4958 } | 4976 } |
| 4959 | 4977 |
| 4960 VISIT_FOR_VALUE(expr->left()); | 4978 VISIT_FOR_VALUE(expr->left()); |
| 4961 VISIT_FOR_VALUE(expr->right()); | 4979 VISIT_FOR_VALUE(expr->right()); |
| 4962 | 4980 |
| 4963 HValue* right = Pop(); | 4981 HValue* right = Pop(); |
| 4964 HValue* left = Pop(); | 4982 HValue* left = Pop(); |
| 4965 Token::Value op = expr->op(); | 4983 Token::Value op = expr->op(); |
| 4966 | 4984 |
| 4967 TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT); | 4985 TypeInfo info = oracle()->CompareType(expr); |
| 4968 HInstruction* instr = NULL; | 4986 HInstruction* instr = NULL; |
| 4969 if (op == Token::INSTANCEOF) { | 4987 if (op == Token::INSTANCEOF) { |
| 4970 // Check to see if the rhs of the instanceof is a global function not | 4988 // Check to see if the rhs of the instanceof is a global function not |
| 4971 // residing in new space. If it is we assume that the function will stay the | 4989 // residing in new space. If it is we assume that the function will stay the |
| 4972 // same. | 4990 // same. |
| 4973 Handle<JSFunction> target = Handle<JSFunction>::null(); | 4991 Handle<JSFunction> target = Handle<JSFunction>::null(); |
| 4974 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); | 4992 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); |
| 4975 bool global_function = (var != NULL) && var->is_global() && !var->is_this(); | 4993 bool global_function = (var != NULL) && var->is_global() && !var->is_this(); |
| 4976 CompilationInfo* info = graph()->info(); | 4994 CompilationInfo* info = graph()->info(); |
| 4977 if (global_function && | 4995 if (global_function && |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5878 } | 5896 } |
| 5879 } | 5897 } |
| 5880 | 5898 |
| 5881 #ifdef DEBUG | 5899 #ifdef DEBUG |
| 5882 if (graph_ != NULL) graph_->Verify(); | 5900 if (graph_ != NULL) graph_->Verify(); |
| 5883 if (allocator_ != NULL) allocator_->Verify(); | 5901 if (allocator_ != NULL) allocator_->Verify(); |
| 5884 #endif | 5902 #endif |
| 5885 } | 5903 } |
| 5886 | 5904 |
| 5887 } } // namespace v8::internal | 5905 } } // namespace v8::internal |
| OLD | NEW |