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 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 } | 1279 } |
1280 | 1280 |
1281 | 1281 |
1282 // Simple sparse set with O(1) add, contains, and clear. | 1282 // Simple sparse set with O(1) add, contains, and clear. |
1283 class SparseSet { | 1283 class SparseSet { |
1284 public: | 1284 public: |
1285 SparseSet(Zone* zone, int capacity) | 1285 SparseSet(Zone* zone, int capacity) |
1286 : capacity_(capacity), | 1286 : capacity_(capacity), |
1287 length_(0), | 1287 length_(0), |
1288 dense_(zone->NewArray<int>(capacity)), | 1288 dense_(zone->NewArray<int>(capacity)), |
1289 sparse_(zone->NewArray<int>(capacity)) {} | 1289 sparse_(zone->NewArray<int>(capacity)) { |
| 1290 #ifndef NVALGRIND |
| 1291 // Initialize the sparse array to make valgrind happy. |
| 1292 memset(sparse_, 0, sizeof(sparse_[0]) * capacity); |
| 1293 #endif |
| 1294 } |
1290 | 1295 |
1291 bool Contains(int n) const { | 1296 bool Contains(int n) const { |
1292 ASSERT(0 <= n && n < capacity_); | 1297 ASSERT(0 <= n && n < capacity_); |
1293 int d = sparse_[n]; | 1298 int d = sparse_[n]; |
1294 return 0 <= d && d < length_ && dense_[d] == n; | 1299 return 0 <= d && d < length_ && dense_[d] == n; |
1295 } | 1300 } |
1296 | 1301 |
1297 bool Add(int n) { | 1302 bool Add(int n) { |
1298 if (Contains(n)) return false; | 1303 if (Contains(n)) return false; |
1299 dense_[length_] = n; | 1304 dense_[length_] = n; |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2000 function_return_(NULL), | 2005 function_return_(NULL), |
2001 test_context_(NULL), | 2006 test_context_(NULL), |
2002 outer_(owner->function_state()) { | 2007 outer_(owner->function_state()) { |
2003 if (outer_ != NULL) { | 2008 if (outer_ != NULL) { |
2004 // State for an inline function. | 2009 // State for an inline function. |
2005 if (owner->ast_context()->IsTest()) { | 2010 if (owner->ast_context()->IsTest()) { |
2006 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); | 2011 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); |
2007 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); | 2012 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); |
2008 if_true->MarkAsInlineReturnTarget(); | 2013 if_true->MarkAsInlineReturnTarget(); |
2009 if_false->MarkAsInlineReturnTarget(); | 2014 if_false->MarkAsInlineReturnTarget(); |
| 2015 Expression* cond = TestContext::cast(owner->ast_context())->condition(); |
2010 // The AstContext constructor pushed on the context stack. This newed | 2016 // The AstContext constructor pushed on the context stack. This newed |
2011 // instance is the reason that AstContext can't be BASE_EMBEDDED. | 2017 // instance is the reason that AstContext can't be BASE_EMBEDDED. |
2012 test_context_ = new TestContext(owner, if_true, if_false); | 2018 test_context_ = new TestContext(owner, cond, if_true, if_false); |
2013 } else { | 2019 } else { |
2014 function_return_ = owner->graph()->CreateBasicBlock(); | 2020 function_return_ = owner->graph()->CreateBasicBlock(); |
2015 function_return()->MarkAsInlineReturnTarget(); | 2021 function_return()->MarkAsInlineReturnTarget(); |
2016 } | 2022 } |
2017 // Set this after possibly allocating a new TestContext above. | 2023 // Set this after possibly allocating a new TestContext above. |
2018 call_context_ = owner->ast_context(); | 2024 call_context_ = owner->ast_context(); |
2019 } | 2025 } |
2020 | 2026 |
2021 // Push on the state stack. | 2027 // Push on the state stack. |
2022 owner->set_function_state(this); | 2028 owner->set_function_state(this); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2172 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); | 2178 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
2173 for_value.set_for_typeof(true); | 2179 for_value.set_for_typeof(true); |
2174 Visit(expr); | 2180 Visit(expr); |
2175 } | 2181 } |
2176 | 2182 |
2177 | 2183 |
2178 | 2184 |
2179 void HGraphBuilder::VisitForControl(Expression* expr, | 2185 void HGraphBuilder::VisitForControl(Expression* expr, |
2180 HBasicBlock* true_block, | 2186 HBasicBlock* true_block, |
2181 HBasicBlock* false_block) { | 2187 HBasicBlock* false_block) { |
2182 TestContext for_test(this, true_block, false_block); | 2188 TestContext for_test(this, expr, true_block, false_block); |
2183 Visit(expr); | 2189 Visit(expr); |
2184 } | 2190 } |
2185 | 2191 |
2186 | 2192 |
2187 void HGraphBuilder::VisitArgument(Expression* expr) { | 2193 void HGraphBuilder::VisitArgument(Expression* expr) { |
2188 CHECK_ALIVE(VisitForValue(expr)); | 2194 CHECK_ALIVE(VisitForValue(expr)); |
2189 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); | 2195 Push(AddInstruction(new(zone()) HPushArgument(Pop()))); |
2190 } | 2196 } |
2191 | 2197 |
2192 | 2198 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2373 // Initialize specials and locals to undefined. | 2379 // Initialize specials and locals to undefined. |
2374 for (int i = environment()->parameter_count() + 1; | 2380 for (int i = environment()->parameter_count() + 1; |
2375 i < environment()->length(); | 2381 i < environment()->length(); |
2376 ++i) { | 2382 ++i) { |
2377 environment()->Bind(i, undefined_constant); | 2383 environment()->Bind(i, undefined_constant); |
2378 } | 2384 } |
2379 | 2385 |
2380 // Handle the arguments and arguments shadow variables specially (they do | 2386 // Handle the arguments and arguments shadow variables specially (they do |
2381 // not have declarations). | 2387 // not have declarations). |
2382 if (scope->arguments() != NULL) { | 2388 if (scope->arguments() != NULL) { |
2383 if (!scope->arguments()->IsStackAllocated()) { | 2389 if (!scope->arguments()->IsStackAllocated() || |
| 2390 (scope->arguments_shadow() != NULL && |
| 2391 !scope->arguments_shadow()->IsStackAllocated())) { |
2384 return Bailout("context-allocated arguments"); | 2392 return Bailout("context-allocated arguments"); |
2385 } | 2393 } |
2386 HArgumentsObject* object = new(zone()) HArgumentsObject; | 2394 HArgumentsObject* object = new(zone()) HArgumentsObject; |
2387 AddInstruction(object); | 2395 AddInstruction(object); |
2388 graph()->SetArgumentsObject(object); | 2396 graph()->SetArgumentsObject(object); |
2389 environment()->Bind(scope->arguments(), object); | 2397 environment()->Bind(scope->arguments(), object); |
| 2398 if (scope->arguments_shadow() != NULL) { |
| 2399 environment()->Bind(scope->arguments_shadow(), object); |
| 2400 } |
2390 } | 2401 } |
2391 } | 2402 } |
2392 | 2403 |
2393 | 2404 |
2394 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { | 2405 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { |
2395 for (int i = 0; i < statements->length(); i++) { | 2406 for (int i = 0; i < statements->length(); i++) { |
2396 CHECK_ALIVE(Visit(statements->at(i))); | 2407 CHECK_ALIVE(Visit(statements->at(i))); |
2397 } | 2408 } |
2398 } | 2409 } |
2399 | 2410 |
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3502 CHECK_ALIVE(VisitForValue(operation)); | 3513 CHECK_ALIVE(VisitForValue(operation)); |
3503 | 3514 |
3504 if (var->is_global()) { | 3515 if (var->is_global()) { |
3505 HandleGlobalVariableAssignment(var, | 3516 HandleGlobalVariableAssignment(var, |
3506 Top(), | 3517 Top(), |
3507 expr->position(), | 3518 expr->position(), |
3508 expr->AssignmentId()); | 3519 expr->AssignmentId()); |
3509 } else if (var->IsStackAllocated()) { | 3520 } else if (var->IsStackAllocated()) { |
3510 Bind(var, Top()); | 3521 Bind(var, Top()); |
3511 } else if (var->IsContextSlot()) { | 3522 } else if (var->IsContextSlot()) { |
3512 // Bail out if we try to mutate a parameter value in a function using | |
3513 // the arguments object. We do not (yet) correctly handle the | |
3514 // arguments property of the function. | |
3515 if (info()->scope()->arguments() != NULL) { | |
3516 // Parameters will rewrite to context slots. We have no direct way | |
3517 // to detect that the variable is a parameter. | |
3518 int count = info()->scope()->num_parameters(); | |
3519 for (int i = 0; i < count; ++i) { | |
3520 if (var == info()->scope()->parameter(i)) { | |
3521 Bailout("assignment to parameter, function uses arguments object"); | |
3522 } | |
3523 } | |
3524 } | |
3525 | |
3526 HValue* context = BuildContextChainWalk(var); | 3523 HValue* context = BuildContextChainWalk(var); |
3527 int index = var->AsSlot()->index(); | 3524 int index = var->AsSlot()->index(); |
3528 HStoreContextSlot* instr = | 3525 HStoreContextSlot* instr = |
3529 new(zone()) HStoreContextSlot(context, index, Top()); | 3526 new(zone()) HStoreContextSlot(context, index, Top()); |
3530 AddInstruction(instr); | 3527 AddInstruction(instr); |
3531 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3528 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3532 } else { | 3529 } else { |
3533 return Bailout("compound assignment to lookup slot"); | 3530 return Bailout("compound assignment to lookup slot"); |
3534 } | 3531 } |
3535 ast_context()->ReturnValue(Pop()); | 3532 ast_context()->ReturnValue(Pop()); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3639 // We do not allow the arguments object to occur in a context where it | 3636 // We do not allow the arguments object to occur in a context where it |
3640 // may escape, but assignments to stack-allocated locals are | 3637 // may escape, but assignments to stack-allocated locals are |
3641 // permitted. | 3638 // permitted. |
3642 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); | 3639 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
3643 HValue* value = Pop(); | 3640 HValue* value = Pop(); |
3644 Bind(var, value); | 3641 Bind(var, value); |
3645 ast_context()->ReturnValue(value); | 3642 ast_context()->ReturnValue(value); |
3646 | 3643 |
3647 } else if (var->IsContextSlot()) { | 3644 } else if (var->IsContextSlot()) { |
3648 ASSERT(var->mode() != Variable::CONST); | 3645 ASSERT(var->mode() != Variable::CONST); |
3649 // Bail out if we try to mutate a parameter value in a function using | |
3650 // the arguments object. We do not (yet) correctly handle the | |
3651 // arguments property of the function. | |
3652 if (info()->scope()->arguments() != NULL) { | |
3653 // Parameters will rewrite to context slots. We have no direct way | |
3654 // to detect that the variable is a parameter. | |
3655 int count = info()->scope()->num_parameters(); | |
3656 for (int i = 0; i < count; ++i) { | |
3657 if (var == info()->scope()->parameter(i)) { | |
3658 Bailout("assignment to parameter, function uses arguments object"); | |
3659 } | |
3660 } | |
3661 } | |
3662 | |
3663 CHECK_ALIVE(VisitForValue(expr->value())); | 3646 CHECK_ALIVE(VisitForValue(expr->value())); |
3664 HValue* context = BuildContextChainWalk(var); | 3647 HValue* context = BuildContextChainWalk(var); |
3665 int index = var->AsSlot()->index(); | 3648 int index = var->AsSlot()->index(); |
3666 HStoreContextSlot* instr = | 3649 HStoreContextSlot* instr = |
3667 new(zone()) HStoreContextSlot(context, index, Top()); | 3650 new(zone()) HStoreContextSlot(context, index, Top()); |
3668 AddInstruction(instr); | 3651 AddInstruction(instr); |
3669 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3652 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3670 ast_context()->ReturnValue(Pop()); | 3653 ast_context()->ReturnValue(Pop()); |
3671 | 3654 |
3672 } else if (var->is_global()) { | 3655 } else if (var->is_global()) { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3918 val = floor_val; | 3901 val = floor_val; |
3919 break; | 3902 break; |
3920 } | 3903 } |
3921 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | 3904 case JSObject::EXTERNAL_FLOAT_ELEMENTS: |
3922 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | 3905 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: |
3923 break; | 3906 break; |
3924 | 3907 |
3925 case JSObject::FAST_ELEMENTS: | 3908 case JSObject::FAST_ELEMENTS: |
3926 case JSObject::FAST_DOUBLE_ELEMENTS: | 3909 case JSObject::FAST_DOUBLE_ELEMENTS: |
3927 case JSObject::DICTIONARY_ELEMENTS: | 3910 case JSObject::DICTIONARY_ELEMENTS: |
3928 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: | |
3929 UNREACHABLE(); | 3911 UNREACHABLE(); |
3930 break; | 3912 break; |
3931 } | 3913 } |
3932 return new(zone()) HStoreKeyedSpecializedArrayElement( | 3914 return new(zone()) HStoreKeyedSpecializedArrayElement( |
3933 external_elements, | 3915 external_elements, |
3934 checked_key, | 3916 checked_key, |
3935 val, | 3917 val, |
3936 map->elements_kind()); | 3918 map->elements_kind()); |
3937 } | 3919 } |
3938 | 3920 |
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4815 var->AsSlot() != NULL && | 4797 var->AsSlot() != NULL && |
4816 var->AsSlot()->type() != Slot::LOOKUP) { | 4798 var->AsSlot()->type() != Slot::LOOKUP) { |
4817 // Result of deleting non-global, non-dynamic variables is false. | 4799 // Result of deleting non-global, non-dynamic variables is false. |
4818 // The subexpression does not have side effects. | 4800 // The subexpression does not have side effects. |
4819 ast_context()->ReturnValue(graph()->GetConstantFalse()); | 4801 ast_context()->ReturnValue(graph()->GetConstantFalse()); |
4820 } else if (prop != NULL) { | 4802 } else if (prop != NULL) { |
4821 if (prop->is_synthetic()) { | 4803 if (prop->is_synthetic()) { |
4822 // Result of deleting parameters is false, even when they rewrite | 4804 // Result of deleting parameters is false, even when they rewrite |
4823 // to accesses on the arguments object. | 4805 // to accesses on the arguments object. |
4824 ast_context()->ReturnValue(graph()->GetConstantFalse()); | 4806 ast_context()->ReturnValue(graph()->GetConstantFalse()); |
4825 } else { | 4807 } else { |
4826 CHECK_ALIVE(VisitForValue(prop->obj())); | 4808 CHECK_ALIVE(VisitForValue(prop->obj())); |
4827 CHECK_ALIVE(VisitForValue(prop->key())); | 4809 CHECK_ALIVE(VisitForValue(prop->key())); |
4828 HValue* key = Pop(); | 4810 HValue* key = Pop(); |
4829 HValue* obj = Pop(); | 4811 HValue* obj = Pop(); |
4830 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); | 4812 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); |
4831 ast_context()->ReturnInstruction(instr, expr->id()); | 4813 ast_context()->ReturnInstruction(instr, expr->id()); |
4832 } | 4814 } |
4833 } else if (var->is_global()) { | 4815 } else if (var->is_global()) { |
4834 Bailout("delete with global variable"); | 4816 Bailout("delete with global variable"); |
4835 } else { | 4817 } else { |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5000 Push(after); | 4982 Push(after); |
5001 | 4983 |
5002 if (var->is_global()) { | 4984 if (var->is_global()) { |
5003 HandleGlobalVariableAssignment(var, | 4985 HandleGlobalVariableAssignment(var, |
5004 after, | 4986 after, |
5005 expr->position(), | 4987 expr->position(), |
5006 expr->AssignmentId()); | 4988 expr->AssignmentId()); |
5007 } else if (var->IsStackAllocated()) { | 4989 } else if (var->IsStackAllocated()) { |
5008 Bind(var, after); | 4990 Bind(var, after); |
5009 } else if (var->IsContextSlot()) { | 4991 } else if (var->IsContextSlot()) { |
5010 // Bail out if we try to mutate a parameter value in a function using | |
5011 // the arguments object. We do not (yet) correctly handle the | |
5012 // arguments property of the function. | |
5013 if (info()->scope()->arguments() != NULL) { | |
5014 // Parameters will rewrite to context slots. We have no direct way | |
5015 // to detect that the variable is a parameter. | |
5016 int count = info()->scope()->num_parameters(); | |
5017 for (int i = 0; i < count; ++i) { | |
5018 if (var == info()->scope()->parameter(i)) { | |
5019 Bailout("assignment to parameter, function uses arguments object"); | |
5020 } | |
5021 } | |
5022 } | |
5023 | |
5024 HValue* context = BuildContextChainWalk(var); | 4992 HValue* context = BuildContextChainWalk(var); |
5025 int index = var->AsSlot()->index(); | 4993 int index = var->AsSlot()->index(); |
5026 HStoreContextSlot* instr = | 4994 HStoreContextSlot* instr = |
5027 new(zone()) HStoreContextSlot(context, index, after); | 4995 new(zone()) HStoreContextSlot(context, index, after); |
5028 AddInstruction(instr); | 4996 AddInstruction(instr); |
5029 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 4997 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
5030 } else { | 4998 } else { |
5031 return Bailout("lookup variable in count operation"); | 4999 return Bailout("lookup variable in count operation"); |
5032 } | 5000 } |
5033 | 5001 |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6439 } | 6407 } |
6440 } | 6408 } |
6441 | 6409 |
6442 #ifdef DEBUG | 6410 #ifdef DEBUG |
6443 if (graph_ != NULL) graph_->Verify(); | 6411 if (graph_ != NULL) graph_->Verify(); |
6444 if (allocator_ != NULL) allocator_->Verify(); | 6412 if (allocator_ != NULL) allocator_->Verify(); |
6445 #endif | 6413 #endif |
6446 } | 6414 } |
6447 | 6415 |
6448 } } // namespace v8::internal | 6416 } } // namespace v8::internal |
OLD | NEW |