| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/control-builders.h" | 8 #include "src/compiler/control-builders.h" |
| 9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 | 154 |
| 155 | 155 |
| 156 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, | 156 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, |
| 157 Scope* scope, | 157 Scope* scope, |
| 158 Node* control_dependency) | 158 Node* control_dependency) |
| 159 : StructuredGraphBuilder::Environment(builder, control_dependency), | 159 : StructuredGraphBuilder::Environment(builder, control_dependency), |
| 160 parameters_count_(scope->num_parameters() + 1), | 160 parameters_count_(scope->num_parameters() + 1), |
| 161 locals_count_(scope->num_stack_slots()), | 161 locals_count_(scope->num_stack_slots()), |
| 162 parameters_node_(NULL), | 162 parameters_node_(NULL), |
| 163 locals_node_(NULL), | 163 locals_node_(NULL), |
| 164 stack_node_(NULL), | 164 stack_node_(NULL) { |
| 165 parameters_dirty_(true), | |
| 166 locals_dirty_(true), | |
| 167 stack_dirty_(true) { | |
| 168 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); | 165 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); |
| 169 | 166 |
| 170 // Bind the receiver variable. | 167 // Bind the receiver variable. |
| 171 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), | 168 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), |
| 172 builder->graph()->start()); | 169 builder->graph()->start()); |
| 173 values()->push_back(receiver); | 170 values()->push_back(receiver); |
| 174 | 171 |
| 175 // Bind all parameter variables. The parameter indices are shifted by 1 | 172 // Bind all parameter variables. The parameter indices are shifted by 1 |
| 176 // (receiver is parameter index -1 but environment index 0). | 173 // (receiver is parameter index -1 but environment index 0). |
| 177 for (int i = 0; i < scope->num_parameters(); ++i) { | 174 for (int i = 0; i < scope->num_parameters(); ++i) { |
| 178 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), | 175 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), |
| 179 builder->graph()->start()); | 176 builder->graph()->start()); |
| 180 values()->push_back(parameter); | 177 values()->push_back(parameter); |
| 181 } | 178 } |
| 182 | 179 |
| 183 // Bind all local variables to undefined. | 180 // Bind all local variables to undefined. |
| 184 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 181 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
| 185 values()->insert(values()->end(), locals_count(), undefined_constant); | 182 values()->insert(values()->end(), locals_count(), undefined_constant); |
| 186 } | 183 } |
| 187 | 184 |
| 188 | 185 |
| 189 AstGraphBuilder::Environment::Environment(const Environment& copy) | 186 AstGraphBuilder::Environment::Environment(const Environment& copy) |
| 190 : StructuredGraphBuilder::Environment( | 187 : StructuredGraphBuilder::Environment( |
| 191 static_cast<StructuredGraphBuilder::Environment>(copy)), | 188 static_cast<StructuredGraphBuilder::Environment>(copy)), |
| 192 parameters_count_(copy.parameters_count_), | 189 parameters_count_(copy.parameters_count_), |
| 193 locals_count_(copy.locals_count_), | 190 locals_count_(copy.locals_count_), |
| 194 parameters_node_(copy.parameters_node_), | 191 parameters_node_(copy.parameters_node_), |
| 195 locals_node_(copy.locals_node_), | 192 locals_node_(copy.locals_node_), |
| 196 stack_node_(copy.stack_node_), | 193 stack_node_(copy.stack_node_) {} |
| 197 parameters_dirty_(copy.parameters_dirty_), | 194 |
| 198 locals_dirty_(copy.locals_dirty_), | 195 |
| 199 stack_dirty_(copy.stack_dirty_) {} | 196 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
| 197 int offset, int count) { |
| 198 bool should_update = false; |
| 199 Node** env_values = (count == 0) ? NULL : &values()->at(offset); |
| 200 if (*state_values == NULL || (*state_values)->InputCount() != count) { |
| 201 should_update = true; |
| 202 } else { |
| 203 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); |
| 204 for (int i = 0; i < count; i++) { |
| 205 if ((*state_values)->InputAt(i) != env_values[i]) { |
| 206 should_update = true; |
| 207 break; |
| 208 } |
| 209 } |
| 210 } |
| 211 if (should_update) { |
| 212 Operator* op = common()->StateValues(count); |
| 213 (*state_values) = graph()->NewNode(op, count, env_values); |
| 214 } |
| 215 } |
| 200 | 216 |
| 201 | 217 |
| 202 Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id) { | 218 Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id) { |
| 203 if (parameters_dirty_) { | 219 UpdateStateValues(¶meters_node_, 0, parameters_count()); |
| 204 Operator* op = common()->StateValues(parameters_count()); | 220 UpdateStateValues(&locals_node_, parameters_count(), locals_count()); |
| 205 if (parameters_count() != 0) { | 221 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), |
| 206 Node** parameters = &values()->front(); | 222 stack_height()); |
| 207 parameters_node_ = graph()->NewNode(op, parameters_count(), parameters); | |
| 208 } else { | |
| 209 parameters_node_ = graph()->NewNode(op); | |
| 210 } | |
| 211 parameters_dirty_ = false; | |
| 212 } | |
| 213 if (locals_dirty_) { | |
| 214 Operator* op = common()->StateValues(locals_count()); | |
| 215 if (locals_count() != 0) { | |
| 216 Node** locals = &values()->at(parameters_count_); | |
| 217 locals_node_ = graph()->NewNode(op, locals_count(), locals); | |
| 218 } else { | |
| 219 locals_node_ = graph()->NewNode(op); | |
| 220 } | |
| 221 locals_dirty_ = false; | |
| 222 } | |
| 223 if (stack_dirty_) { | |
| 224 Operator* op = common()->StateValues(stack_height()); | |
| 225 if (stack_height() != 0) { | |
| 226 Node** stack = &values()->at(parameters_count_ + locals_count_); | |
| 227 stack_node_ = graph()->NewNode(op, stack_height(), stack); | |
| 228 } else { | |
| 229 stack_node_ = graph()->NewNode(op); | |
| 230 } | |
| 231 stack_dirty_ = false; | |
| 232 } | |
| 233 | 223 |
| 234 Operator* op = common()->FrameState(ast_id); | 224 Operator* op = common()->FrameState(ast_id); |
| 235 | 225 |
| 236 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_); | 226 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_); |
| 237 } | 227 } |
| 238 | 228 |
| 239 | 229 |
| 240 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, | 230 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, |
| 241 Expression::Context kind, | 231 Expression::Context kind) |
| 242 BailoutId bailout_id) | 232 : kind_(kind), owner_(own), outer_(own->ast_context()) { |
| 243 : bailout_id_(bailout_id), | |
| 244 kind_(kind), | |
| 245 owner_(own), | |
| 246 outer_(own->ast_context()) { | |
| 247 owner()->set_ast_context(this); // Push. | 233 owner()->set_ast_context(this); // Push. |
| 248 #ifdef DEBUG | 234 #ifdef DEBUG |
| 249 original_height_ = environment()->stack_height(); | 235 original_height_ = environment()->stack_height(); |
| 250 #endif | 236 #endif |
| 251 } | 237 } |
| 252 | 238 |
| 253 | 239 |
| 254 AstGraphBuilder::AstContext::~AstContext() { | 240 AstGraphBuilder::AstContext::~AstContext() { |
| 255 owner()->set_ast_context(outer_); // Pop. | 241 owner()->set_ast_context(outer_); // Pop. |
| 256 } | 242 } |
| 257 | 243 |
| 258 | 244 |
| 259 AstGraphBuilder::AstEffectContext::~AstEffectContext() { | 245 AstGraphBuilder::AstEffectContext::~AstEffectContext() { |
| 260 DCHECK(environment()->stack_height() == original_height_); | 246 DCHECK(environment()->stack_height() == original_height_); |
| 261 } | 247 } |
| 262 | 248 |
| 263 | 249 |
| 264 AstGraphBuilder::AstValueContext::~AstValueContext() { | 250 AstGraphBuilder::AstValueContext::~AstValueContext() { |
| 265 DCHECK(environment()->stack_height() == original_height_ + 1); | 251 DCHECK(environment()->stack_height() == original_height_ + 1); |
| 266 } | 252 } |
| 267 | 253 |
| 268 | 254 |
| 269 AstGraphBuilder::AstTestContext::~AstTestContext() { | 255 AstGraphBuilder::AstTestContext::~AstTestContext() { |
| 270 DCHECK(environment()->stack_height() == original_height_ + 1); | 256 DCHECK(environment()->stack_height() == original_height_ + 1); |
| 271 } | 257 } |
| 272 | 258 |
| 273 | 259 |
| 274 void AstGraphBuilder::AstEffectContext::ProduceValueWithLazyBailout( | |
| 275 Node* value) { | |
| 276 ProduceValue(value); | |
| 277 owner()->BuildLazyBailout(value, bailout_id_); | |
| 278 } | |
| 279 | |
| 280 | |
| 281 void AstGraphBuilder::AstValueContext::ProduceValueWithLazyBailout( | |
| 282 Node* value) { | |
| 283 ProduceValue(value); | |
| 284 owner()->BuildLazyBailout(value, bailout_id_); | |
| 285 } | |
| 286 | |
| 287 | |
| 288 void AstGraphBuilder::AstTestContext::ProduceValueWithLazyBailout(Node* value) { | |
| 289 environment()->Push(value); | |
| 290 owner()->BuildLazyBailout(value, bailout_id_); | |
| 291 environment()->Pop(); | |
| 292 ProduceValue(value); | |
| 293 } | |
| 294 | |
| 295 | |
| 296 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { | 260 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { |
| 297 // The value is ignored. | 261 // The value is ignored. |
| 298 } | 262 } |
| 299 | 263 |
| 300 | 264 |
| 301 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { | 265 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { |
| 302 environment()->Push(value); | 266 environment()->Push(value); |
| 303 } | 267 } |
| 304 | 268 |
| 305 | 269 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 | 316 |
| 353 | 317 |
| 354 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { | 318 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { |
| 355 for (int i = 0; i < exprs->length(); ++i) { | 319 for (int i = 0; i < exprs->length(); ++i) { |
| 356 VisitForValue(exprs->at(i)); | 320 VisitForValue(exprs->at(i)); |
| 357 } | 321 } |
| 358 } | 322 } |
| 359 | 323 |
| 360 | 324 |
| 361 void AstGraphBuilder::VisitForValue(Expression* expr) { | 325 void AstGraphBuilder::VisitForValue(Expression* expr) { |
| 362 AstValueContext for_value(this, expr->id()); | 326 AstValueContext for_value(this); |
| 363 if (!HasStackOverflow()) { | 327 if (!HasStackOverflow()) { |
| 364 expr->Accept(this); | 328 expr->Accept(this); |
| 365 } | 329 } |
| 366 } | 330 } |
| 367 | 331 |
| 368 | 332 |
| 369 void AstGraphBuilder::VisitForEffect(Expression* expr) { | 333 void AstGraphBuilder::VisitForEffect(Expression* expr) { |
| 370 AstEffectContext for_effect(this, expr->id()); | 334 AstEffectContext for_effect(this); |
| 371 if (!HasStackOverflow()) { | 335 if (!HasStackOverflow()) { |
| 372 expr->Accept(this); | 336 expr->Accept(this); |
| 373 } | 337 } |
| 374 } | 338 } |
| 375 | 339 |
| 376 | 340 |
| 377 void AstGraphBuilder::VisitForTest(Expression* expr) { | 341 void AstGraphBuilder::VisitForTest(Expression* expr) { |
| 378 AstTestContext for_condition(this, expr->id()); | 342 AstTestContext for_condition(this); |
| 379 if (!HasStackOverflow()) { | 343 if (!HasStackOverflow()) { |
| 380 expr->Accept(this); | 344 expr->Accept(this); |
| 381 } | 345 } |
| 382 } | 346 } |
| 383 | 347 |
| 384 | 348 |
| 385 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { | 349 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { |
| 386 Variable* variable = decl->proxy()->var(); | 350 Variable* variable = decl->proxy()->var(); |
| 387 VariableMode mode = decl->mode(); | 351 VariableMode mode = decl->mode(); |
| 388 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; | 352 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 environment()->Push(cache_length); | 670 environment()->Push(cache_length); |
| 707 environment()->Push(jsgraph()->ZeroConstant()); | 671 environment()->Push(jsgraph()->ZeroConstant()); |
| 708 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 672 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 709 LoopBuilder for_loop(this); | 673 LoopBuilder for_loop(this); |
| 710 for_loop.BeginLoop(); | 674 for_loop.BeginLoop(); |
| 711 // Check loop termination condition. | 675 // Check loop termination condition. |
| 712 Node* index = environment()->Peek(0); | 676 Node* index = environment()->Peek(0); |
| 713 Node* exit_cond = | 677 Node* exit_cond = |
| 714 NewNode(javascript()->LessThan(), index, cache_length); | 678 NewNode(javascript()->LessThan(), index, cache_length); |
| 715 // TODO(jarin): provide real bailout id. | 679 // TODO(jarin): provide real bailout id. |
| 716 BuildLazyBailout(exit_cond, BailoutId::None()); | 680 PrepareFrameState(exit_cond, BailoutId::None()); |
| 717 for_loop.BreakUnless(exit_cond); | 681 for_loop.BreakUnless(exit_cond); |
| 718 // TODO(dcarney): this runtime call should be a handful of | 682 // TODO(dcarney): this runtime call should be a handful of |
| 719 // simplified instructions that | 683 // simplified instructions that |
| 720 // basically produce | 684 // basically produce |
| 721 // value = array[index] | 685 // value = array[index] |
| 722 environment()->Push(obj); | 686 environment()->Push(obj); |
| 723 environment()->Push(cache_array); | 687 environment()->Push(cache_array); |
| 724 environment()->Push(cache_type); | 688 environment()->Push(cache_type); |
| 725 environment()->Push(index); | 689 environment()->Push(index); |
| 726 Node* pair = | 690 Node* pair = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 746 environment()->Push(jsgraph()->HeapConstant(function)); | 710 environment()->Push(jsgraph()->HeapConstant(function)); |
| 747 // Receiver. | 711 // Receiver. |
| 748 environment()->Push(obj); | 712 environment()->Push(obj); |
| 749 // Args. | 713 // Args. |
| 750 environment()->Push(value); | 714 environment()->Push(value); |
| 751 // result is either the string key or Smi(0) indicating the property | 715 // result is either the string key or Smi(0) indicating the property |
| 752 // is gone. | 716 // is gone. |
| 753 Node* res = ProcessArguments( | 717 Node* res = ProcessArguments( |
| 754 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); | 718 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); |
| 755 // TODO(jarin): provide real bailout id. | 719 // TODO(jarin): provide real bailout id. |
| 756 BuildLazyBailout(res, BailoutId::None()); | 720 PrepareFrameState(res, BailoutId::None()); |
| 757 Node* property_missing = NewNode(javascript()->StrictEqual(), res, | 721 Node* property_missing = NewNode(javascript()->StrictEqual(), res, |
| 758 jsgraph()->ZeroConstant()); | 722 jsgraph()->ZeroConstant()); |
| 759 { | 723 { |
| 760 IfBuilder is_property_missing(this); | 724 IfBuilder is_property_missing(this); |
| 761 is_property_missing.If(property_missing); | 725 is_property_missing.If(property_missing); |
| 762 is_property_missing.Then(); | 726 is_property_missing.Then(); |
| 763 // Inc counter and continue. | 727 // Inc counter and continue. |
| 764 Node* index_inc = | 728 Node* index_inc = |
| 765 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 729 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
| 730 // TODO(jarin): provide real bailout id. |
| 731 PrepareFrameState(index_inc, BailoutId::None()); |
| 766 environment()->Poke(0, index_inc); | 732 environment()->Poke(0, index_inc); |
| 767 // TODO(jarin): provide real bailout id. | |
| 768 BuildLazyBailout(index_inc, BailoutId::None()); | |
| 769 for_loop.Continue(); | 733 for_loop.Continue(); |
| 770 is_property_missing.Else(); | 734 is_property_missing.Else(); |
| 771 is_property_missing.End(); | 735 is_property_missing.End(); |
| 772 } | 736 } |
| 773 // Replace 'value' in environment. | 737 // Replace 'value' in environment. |
| 774 environment()->Push(res); | 738 environment()->Push(res); |
| 775 test_should_filter.Else(); | 739 test_should_filter.Else(); |
| 776 test_should_filter.End(); | 740 test_should_filter.End(); |
| 777 } | 741 } |
| 778 value = environment()->Pop(); | 742 value = environment()->Pop(); |
| 779 // Bind value and do loop body. | 743 // Bind value and do loop body. |
| 780 VisitForInAssignment(stmt->each(), value); | 744 VisitForInAssignment(stmt->each(), value); |
| 781 VisitIterationBody(stmt, &for_loop, 5); | 745 VisitIterationBody(stmt, &for_loop, 5); |
| 782 // Inc counter and continue. | 746 // Inc counter and continue. |
| 783 Node* index_inc = | 747 Node* index_inc = |
| 784 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 748 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
| 749 // TODO(jarin): provide real bailout id. |
| 750 PrepareFrameState(index_inc, BailoutId::None()); |
| 785 environment()->Poke(0, index_inc); | 751 environment()->Poke(0, index_inc); |
| 786 // TODO(jarin): provide real bailout id. | |
| 787 BuildLazyBailout(index_inc, BailoutId::None()); | |
| 788 for_loop.EndBody(); | 752 for_loop.EndBody(); |
| 789 for_loop.EndLoop(); | 753 for_loop.EndLoop(); |
| 790 environment()->Drop(5); | 754 environment()->Drop(5); |
| 791 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 755 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 792 } | 756 } |
| 793 have_no_properties.End(); | 757 have_no_properties.End(); |
| 794 } | 758 } |
| 795 is_null.End(); | 759 is_null.End(); |
| 796 } | 760 } |
| 797 is_undefined.End(); | 761 is_undefined.End(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 810 } | 774 } |
| 811 | 775 |
| 812 | 776 |
| 813 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 777 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| 814 UNREACHABLE(); | 778 UNREACHABLE(); |
| 815 } | 779 } |
| 816 | 780 |
| 817 | 781 |
| 818 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 782 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 819 // TODO(turbofan): Do we really need a separate reloc-info for this? | 783 // TODO(turbofan): Do we really need a separate reloc-info for this? |
| 820 NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0)); | 784 Node* node = NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0)); |
| 785 PrepareFrameState(node, stmt->DebugBreakId()); |
| 821 } | 786 } |
| 822 | 787 |
| 823 | 788 |
| 824 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 789 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 825 Node* context = current_context(); | 790 Node* context = current_context(); |
| 826 | 791 |
| 827 // Build a new shared function info if we cannot find one in the baseline | 792 // Build a new shared function info if we cannot find one in the baseline |
| 828 // code. We also have a stack overflow if the recursive compilation did. | 793 // code. We also have a stack overflow if the recursive compilation did. |
| 829 Handle<SharedFunctionInfo> shared_info = | 794 Handle<SharedFunctionInfo> shared_info = |
| 830 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); | 795 SearchSharedFunctionInfo(info()->shared_info()->code(), expr); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 case ObjectLiteral::Property::COMPUTED: { | 890 case ObjectLiteral::Property::COMPUTED: { |
| 926 // It is safe to use [[Put]] here because the boilerplate already | 891 // It is safe to use [[Put]] here because the boilerplate already |
| 927 // contains computed properties with an uninitialized value. | 892 // contains computed properties with an uninitialized value. |
| 928 if (key->value()->IsInternalizedString()) { | 893 if (key->value()->IsInternalizedString()) { |
| 929 if (property->emit_store()) { | 894 if (property->emit_store()) { |
| 930 VisitForValue(property->value()); | 895 VisitForValue(property->value()); |
| 931 Node* value = environment()->Pop(); | 896 Node* value = environment()->Pop(); |
| 932 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); | 897 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); |
| 933 Node* store = | 898 Node* store = |
| 934 NewNode(javascript()->StoreNamed(name), literal, value); | 899 NewNode(javascript()->StoreNamed(name), literal, value); |
| 935 BuildLazyBailout(store, key->id()); | 900 PrepareFrameState(store, key->id()); |
| 936 } else { | 901 } else { |
| 937 VisitForEffect(property->value()); | 902 VisitForEffect(property->value()); |
| 938 } | 903 } |
| 939 break; | 904 break; |
| 940 } | 905 } |
| 941 environment()->Push(literal); // Duplicate receiver. | 906 environment()->Push(literal); // Duplicate receiver. |
| 942 VisitForValue(property->key()); | 907 VisitForValue(property->key()); |
| 943 VisitForValue(property->value()); | 908 VisitForValue(property->value()); |
| 944 Node* value = environment()->Pop(); | 909 Node* value = environment()->Pop(); |
| 945 Node* key = environment()->Pop(); | 910 Node* key = environment()->Pop(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 // Create nodes to evaluate all the non-constant subexpressions and to store | 982 // Create nodes to evaluate all the non-constant subexpressions and to store |
| 1018 // them into the newly cloned array. | 983 // them into the newly cloned array. |
| 1019 for (int i = 0; i < expr->values()->length(); i++) { | 984 for (int i = 0; i < expr->values()->length(); i++) { |
| 1020 Expression* subexpr = expr->values()->at(i); | 985 Expression* subexpr = expr->values()->at(i); |
| 1021 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 986 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 1022 | 987 |
| 1023 VisitForValue(subexpr); | 988 VisitForValue(subexpr); |
| 1024 Node* value = environment()->Pop(); | 989 Node* value = environment()->Pop(); |
| 1025 Node* index = jsgraph()->Constant(i); | 990 Node* index = jsgraph()->Constant(i); |
| 1026 Node* store = NewNode(javascript()->StoreProperty(), literal, index, value); | 991 Node* store = NewNode(javascript()->StoreProperty(), literal, index, value); |
| 1027 BuildLazyBailout(store, expr->GetIdForElement(i)); | 992 PrepareFrameState(store, expr->GetIdForElement(i)); |
| 1028 } | 993 } |
| 1029 | 994 |
| 1030 environment()->Pop(); // Array literal index. | 995 environment()->Pop(); // Array literal index. |
| 1031 ast_context()->ProduceValue(environment()->Pop()); | 996 ast_context()->ProduceValue(environment()->Pop()); |
| 1032 } | 997 } |
| 1033 | 998 |
| 1034 | 999 |
| 1035 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { | 1000 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { |
| 1036 DCHECK(expr->IsValidReferenceExpression()); | 1001 DCHECK(expr->IsValidReferenceExpression()); |
| 1037 | 1002 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1049 } | 1014 } |
| 1050 case NAMED_PROPERTY: { | 1015 case NAMED_PROPERTY: { |
| 1051 environment()->Push(value); | 1016 environment()->Push(value); |
| 1052 VisitForValue(property->obj()); | 1017 VisitForValue(property->obj()); |
| 1053 Node* object = environment()->Pop(); | 1018 Node* object = environment()->Pop(); |
| 1054 value = environment()->Pop(); | 1019 value = environment()->Pop(); |
| 1055 PrintableUnique<Name> name = | 1020 PrintableUnique<Name> name = |
| 1056 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1021 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
| 1057 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1022 Node* store = NewNode(javascript()->StoreNamed(name), object, value); |
| 1058 // TODO(jarin) Fill in the correct bailout id. | 1023 // TODO(jarin) Fill in the correct bailout id. |
| 1059 BuildLazyBailout(store, BailoutId::None()); | 1024 PrepareFrameState(store, BailoutId::None()); |
| 1060 break; | 1025 break; |
| 1061 } | 1026 } |
| 1062 case KEYED_PROPERTY: { | 1027 case KEYED_PROPERTY: { |
| 1063 environment()->Push(value); | 1028 environment()->Push(value); |
| 1064 VisitForValue(property->obj()); | 1029 VisitForValue(property->obj()); |
| 1065 VisitForValue(property->key()); | 1030 VisitForValue(property->key()); |
| 1066 Node* key = environment()->Pop(); | 1031 Node* key = environment()->Pop(); |
| 1067 Node* object = environment()->Pop(); | 1032 Node* object = environment()->Pop(); |
| 1068 value = environment()->Pop(); | 1033 value = environment()->Pop(); |
| 1069 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1034 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); |
| 1070 // TODO(jarin) Fill in the correct bailout id. | 1035 // TODO(jarin) Fill in the correct bailout id. |
| 1071 BuildLazyBailout(store, BailoutId::None()); | 1036 PrepareFrameState(store, BailoutId::None()); |
| 1072 break; | 1037 break; |
| 1073 } | 1038 } |
| 1074 } | 1039 } |
| 1075 } | 1040 } |
| 1076 | 1041 |
| 1077 | 1042 |
| 1078 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 1043 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
| 1079 DCHECK(expr->target()->IsValidReferenceExpression()); | 1044 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1080 | 1045 |
| 1081 // Left-hand side can only be a property, a global or a variable slot. | 1046 // Left-hand side can only be a property, a global or a variable slot. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1105 case VARIABLE: { | 1070 case VARIABLE: { |
| 1106 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1071 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 1107 old_value = BuildVariableLoad(variable, expr->target()->id()); | 1072 old_value = BuildVariableLoad(variable, expr->target()->id()); |
| 1108 break; | 1073 break; |
| 1109 } | 1074 } |
| 1110 case NAMED_PROPERTY: { | 1075 case NAMED_PROPERTY: { |
| 1111 Node* object = environment()->Top(); | 1076 Node* object = environment()->Top(); |
| 1112 PrintableUnique<Name> name = | 1077 PrintableUnique<Name> name = |
| 1113 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1078 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
| 1114 old_value = NewNode(javascript()->LoadNamed(name), object); | 1079 old_value = NewNode(javascript()->LoadNamed(name), object); |
| 1115 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1080 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
| 1116 break; | 1081 break; |
| 1117 } | 1082 } |
| 1118 case KEYED_PROPERTY: { | 1083 case KEYED_PROPERTY: { |
| 1119 Node* key = environment()->Top(); | 1084 Node* key = environment()->Top(); |
| 1120 Node* object = environment()->Peek(1); | 1085 Node* object = environment()->Peek(1); |
| 1121 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1086 old_value = NewNode(javascript()->LoadProperty(), object, key); |
| 1122 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1087 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
| 1123 break; | 1088 break; |
| 1124 } | 1089 } |
| 1125 } | 1090 } |
| 1126 environment()->Push(old_value); | 1091 environment()->Push(old_value); |
| 1127 VisitForValue(expr->value()); | 1092 VisitForValue(expr->value()); |
| 1128 Node* right = environment()->Pop(); | 1093 Node* right = environment()->Pop(); |
| 1129 Node* left = environment()->Pop(); | 1094 Node* left = environment()->Pop(); |
| 1130 Node* value = BuildBinaryOp(left, right, expr->binary_op()); | 1095 Node* value = BuildBinaryOp(left, right, expr->binary_op()); |
| 1096 PrepareFrameState(value, expr->binary_operation()->id(), PUSH_OUTPUT); |
| 1131 environment()->Push(value); | 1097 environment()->Push(value); |
| 1132 BuildLazyBailout(value, expr->binary_operation()->id()); | |
| 1133 } else { | 1098 } else { |
| 1134 VisitForValue(expr->value()); | 1099 VisitForValue(expr->value()); |
| 1135 } | 1100 } |
| 1136 | 1101 |
| 1137 // Store the value. | 1102 // Store the value. |
| 1138 Node* value = environment()->Pop(); | 1103 Node* value = environment()->Pop(); |
| 1139 switch (assign_type) { | 1104 switch (assign_type) { |
| 1140 case VARIABLE: { | 1105 case VARIABLE: { |
| 1141 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1106 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 1142 BuildVariableAssignment(variable, value, expr->op(), | 1107 BuildVariableAssignment(variable, value, expr->op(), |
| 1143 expr->AssignmentId()); | 1108 expr->AssignmentId()); |
| 1144 break; | 1109 break; |
| 1145 } | 1110 } |
| 1146 case NAMED_PROPERTY: { | 1111 case NAMED_PROPERTY: { |
| 1147 Node* object = environment()->Pop(); | 1112 Node* object = environment()->Pop(); |
| 1148 PrintableUnique<Name> name = | 1113 PrintableUnique<Name> name = |
| 1149 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1114 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
| 1150 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1115 Node* store = NewNode(javascript()->StoreNamed(name), object, value); |
| 1151 BuildLazyBailout(store, expr->AssignmentId()); | 1116 PrepareFrameState(store, expr->AssignmentId()); |
| 1152 break; | 1117 break; |
| 1153 } | 1118 } |
| 1154 case KEYED_PROPERTY: { | 1119 case KEYED_PROPERTY: { |
| 1155 Node* key = environment()->Pop(); | 1120 Node* key = environment()->Pop(); |
| 1156 Node* object = environment()->Pop(); | 1121 Node* object = environment()->Pop(); |
| 1157 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1122 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); |
| 1158 BuildLazyBailout(store, expr->AssignmentId()); | 1123 PrepareFrameState(store, expr->AssignmentId()); |
| 1159 break; | 1124 break; |
| 1160 } | 1125 } |
| 1161 } | 1126 } |
| 1162 | 1127 |
| 1163 ast_context()->ProduceValue(value); | 1128 ast_context()->ProduceValue(value); |
| 1164 } | 1129 } |
| 1165 | 1130 |
| 1166 | 1131 |
| 1167 void AstGraphBuilder::VisitYield(Yield* expr) { | 1132 void AstGraphBuilder::VisitYield(Yield* expr) { |
| 1168 VisitForValue(expr->generator_object()); | 1133 VisitForValue(expr->generator_object()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1191 PrintableUnique<Name> name = | 1156 PrintableUnique<Name> name = |
| 1192 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); | 1157 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); |
| 1193 value = NewNode(javascript()->LoadNamed(name), object); | 1158 value = NewNode(javascript()->LoadNamed(name), object); |
| 1194 } else { | 1159 } else { |
| 1195 VisitForValue(expr->obj()); | 1160 VisitForValue(expr->obj()); |
| 1196 VisitForValue(expr->key()); | 1161 VisitForValue(expr->key()); |
| 1197 Node* key = environment()->Pop(); | 1162 Node* key = environment()->Pop(); |
| 1198 Node* object = environment()->Pop(); | 1163 Node* object = environment()->Pop(); |
| 1199 value = NewNode(javascript()->LoadProperty(), object, key); | 1164 value = NewNode(javascript()->LoadProperty(), object, key); |
| 1200 } | 1165 } |
| 1201 ast_context()->ProduceValueWithLazyBailout(value); | 1166 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1167 ast_context()->ProduceValue(value); |
| 1202 } | 1168 } |
| 1203 | 1169 |
| 1204 | 1170 |
| 1205 void AstGraphBuilder::VisitCall(Call* expr) { | 1171 void AstGraphBuilder::VisitCall(Call* expr) { |
| 1206 Expression* callee = expr->expression(); | 1172 Expression* callee = expr->expression(); |
| 1207 Call::CallType call_type = expr->GetCallType(isolate()); | 1173 Call::CallType call_type = expr->GetCallType(isolate()); |
| 1208 | 1174 |
| 1209 // Prepare the callee and the receiver to the function call. This depends on | 1175 // Prepare the callee and the receiver to the function call. This depends on |
| 1210 // the semantics of the underlying call type. | 1176 // the semantics of the underlying call type. |
| 1211 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1177 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1235 Node* object = environment()->Top(); | 1201 Node* object = environment()->Top(); |
| 1236 if (property->key()->IsPropertyName()) { | 1202 if (property->key()->IsPropertyName()) { |
| 1237 PrintableUnique<Name> name = | 1203 PrintableUnique<Name> name = |
| 1238 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1204 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
| 1239 callee_value = NewNode(javascript()->LoadNamed(name), object); | 1205 callee_value = NewNode(javascript()->LoadNamed(name), object); |
| 1240 } else { | 1206 } else { |
| 1241 VisitForValue(property->key()); | 1207 VisitForValue(property->key()); |
| 1242 Node* key = environment()->Pop(); | 1208 Node* key = environment()->Pop(); |
| 1243 callee_value = NewNode(javascript()->LoadProperty(), object, key); | 1209 callee_value = NewNode(javascript()->LoadProperty(), object, key); |
| 1244 } | 1210 } |
| 1245 BuildLazyBailoutWithPushedNode(callee_value, property->LoadId()); | 1211 PrepareFrameState(callee_value, property->LoadId(), PUSH_OUTPUT); |
| 1246 receiver_value = environment()->Pop(); | 1212 receiver_value = environment()->Pop(); |
| 1247 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 1213 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an |
| 1248 // object for sloppy callees. This could also be modeled explicitly here, | 1214 // object for sloppy callees. This could also be modeled explicitly here, |
| 1249 // thereby obsoleting the need for a flag to the call operator. | 1215 // thereby obsoleting the need for a flag to the call operator. |
| 1250 flags = CALL_AS_METHOD; | 1216 flags = CALL_AS_METHOD; |
| 1251 break; | 1217 break; |
| 1252 } | 1218 } |
| 1253 case Call::POSSIBLY_EVAL_CALL: | 1219 case Call::POSSIBLY_EVAL_CALL: |
| 1254 possibly_eval = true; | 1220 possibly_eval = true; |
| 1255 // Fall through. | 1221 // Fall through. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 Node* new_receiver = NewNode(common()->Projection(1), pair); | 1256 Node* new_receiver = NewNode(common()->Projection(1), pair); |
| 1291 | 1257 |
| 1292 // Patch callee and receiver on the environment. | 1258 // Patch callee and receiver on the environment. |
| 1293 environment()->Poke(arg_count + 1, new_callee); | 1259 environment()->Poke(arg_count + 1, new_callee); |
| 1294 environment()->Poke(arg_count + 0, new_receiver); | 1260 environment()->Poke(arg_count + 0, new_receiver); |
| 1295 } | 1261 } |
| 1296 | 1262 |
| 1297 // Create node to perform the function call. | 1263 // Create node to perform the function call. |
| 1298 Operator* call = javascript()->Call(args->length() + 2, flags); | 1264 Operator* call = javascript()->Call(args->length() + 2, flags); |
| 1299 Node* value = ProcessArguments(call, args->length() + 2); | 1265 Node* value = ProcessArguments(call, args->length() + 2); |
| 1300 ast_context()->ProduceValueWithLazyBailout(value); | 1266 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1267 ast_context()->ProduceValue(value); |
| 1301 } | 1268 } |
| 1302 | 1269 |
| 1303 | 1270 |
| 1304 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 1271 void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
| 1305 VisitForValue(expr->expression()); | 1272 VisitForValue(expr->expression()); |
| 1306 | 1273 |
| 1307 // Evaluate all arguments to the construct call. | 1274 // Evaluate all arguments to the construct call. |
| 1308 ZoneList<Expression*>* args = expr->arguments(); | 1275 ZoneList<Expression*>* args = expr->arguments(); |
| 1309 VisitForValues(args); | 1276 VisitForValues(args); |
| 1310 | 1277 |
| 1311 // Create node to perform the construct call. | 1278 // Create node to perform the construct call. |
| 1312 Operator* call = javascript()->CallNew(args->length() + 1); | 1279 Operator* call = javascript()->CallNew(args->length() + 1); |
| 1313 Node* value = ProcessArguments(call, args->length() + 1); | 1280 Node* value = ProcessArguments(call, args->length() + 1); |
| 1314 ast_context()->ProduceValueWithLazyBailout(value); | 1281 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1282 ast_context()->ProduceValue(value); |
| 1315 } | 1283 } |
| 1316 | 1284 |
| 1317 | 1285 |
| 1318 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 1286 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
| 1319 Handle<String> name = expr->name(); | 1287 Handle<String> name = expr->name(); |
| 1320 | 1288 |
| 1321 // The callee and the receiver both have to be pushed onto the operand stack | 1289 // The callee and the receiver both have to be pushed onto the operand stack |
| 1322 // before arguments are being evaluated. | 1290 // before arguments are being evaluated. |
| 1323 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1291 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
| 1324 Node* receiver_value = BuildLoadBuiltinsObject(); | 1292 Node* receiver_value = BuildLoadBuiltinsObject(); |
| 1325 PrintableUnique<String> unique = MakeUnique(name); | 1293 PrintableUnique<String> unique = MakeUnique(name); |
| 1326 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); | 1294 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); |
| 1327 environment()->Push(callee_value); | |
| 1328 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft | 1295 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft |
| 1329 // refuses to optimize functions with jsruntime calls). | 1296 // refuses to optimize functions with jsruntime calls). |
| 1330 BuildLazyBailout(callee_value, BailoutId::None()); | 1297 PrepareFrameState(callee_value, BailoutId::None(), PUSH_OUTPUT); |
| 1298 environment()->Push(callee_value); |
| 1331 environment()->Push(receiver_value); | 1299 environment()->Push(receiver_value); |
| 1332 | 1300 |
| 1333 // Evaluate all arguments to the JS runtime call. | 1301 // Evaluate all arguments to the JS runtime call. |
| 1334 ZoneList<Expression*>* args = expr->arguments(); | 1302 ZoneList<Expression*>* args = expr->arguments(); |
| 1335 VisitForValues(args); | 1303 VisitForValues(args); |
| 1336 | 1304 |
| 1337 // Create node to perform the JS runtime call. | 1305 // Create node to perform the JS runtime call. |
| 1338 Operator* call = javascript()->Call(args->length() + 2, flags); | 1306 Operator* call = javascript()->Call(args->length() + 2, flags); |
| 1339 Node* value = ProcessArguments(call, args->length() + 2); | 1307 Node* value = ProcessArguments(call, args->length() + 2); |
| 1340 ast_context()->ProduceValueWithLazyBailout(value); | 1308 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1309 ast_context()->ProduceValue(value); |
| 1341 } | 1310 } |
| 1342 | 1311 |
| 1343 | 1312 |
| 1344 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 1313 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
| 1345 const Runtime::Function* function = expr->function(); | 1314 const Runtime::Function* function = expr->function(); |
| 1346 | 1315 |
| 1347 // Handle calls to runtime functions implemented in JavaScript separately as | 1316 // Handle calls to runtime functions implemented in JavaScript separately as |
| 1348 // the call follows JavaScript ABI and the callee is statically unknown. | 1317 // the call follows JavaScript ABI and the callee is statically unknown. |
| 1349 if (expr->is_jsruntime()) { | 1318 if (expr->is_jsruntime()) { |
| 1350 DCHECK(function == NULL && expr->name()->length() > 0); | 1319 DCHECK(function == NULL && expr->name()->length() > 0); |
| 1351 return VisitCallJSRuntime(expr); | 1320 return VisitCallJSRuntime(expr); |
| 1352 } | 1321 } |
| 1353 | 1322 |
| 1354 // Evaluate all arguments to the runtime call. | 1323 // Evaluate all arguments to the runtime call. |
| 1355 ZoneList<Expression*>* args = expr->arguments(); | 1324 ZoneList<Expression*>* args = expr->arguments(); |
| 1356 VisitForValues(args); | 1325 VisitForValues(args); |
| 1357 | 1326 |
| 1358 // Create node to perform the runtime call. | 1327 // Create node to perform the runtime call. |
| 1359 Runtime::FunctionId functionId = function->function_id; | 1328 Runtime::FunctionId functionId = function->function_id; |
| 1360 Operator* call = javascript()->Runtime(functionId, args->length()); | 1329 Operator* call = javascript()->Runtime(functionId, args->length()); |
| 1361 Node* value = ProcessArguments(call, args->length()); | 1330 Node* value = ProcessArguments(call, args->length()); |
| 1362 ast_context()->ProduceValueWithLazyBailout(value); | 1331 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1332 ast_context()->ProduceValue(value); |
| 1363 } | 1333 } |
| 1364 | 1334 |
| 1365 | 1335 |
| 1366 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 1336 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| 1367 switch (expr->op()) { | 1337 switch (expr->op()) { |
| 1368 case Token::DELETE: | 1338 case Token::DELETE: |
| 1369 return VisitDelete(expr); | 1339 return VisitDelete(expr); |
| 1370 case Token::VOID: | 1340 case Token::VOID: |
| 1371 return VisitVoid(expr); | 1341 return VisitVoid(expr); |
| 1372 case Token::TYPEOF: | 1342 case Token::TYPEOF: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1399 old_value = BuildVariableLoad(variable, expr->expression()->id()); | 1369 old_value = BuildVariableLoad(variable, expr->expression()->id()); |
| 1400 stack_depth = 0; | 1370 stack_depth = 0; |
| 1401 break; | 1371 break; |
| 1402 } | 1372 } |
| 1403 case NAMED_PROPERTY: { | 1373 case NAMED_PROPERTY: { |
| 1404 VisitForValue(property->obj()); | 1374 VisitForValue(property->obj()); |
| 1405 Node* object = environment()->Top(); | 1375 Node* object = environment()->Top(); |
| 1406 PrintableUnique<Name> name = | 1376 PrintableUnique<Name> name = |
| 1407 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1377 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
| 1408 old_value = NewNode(javascript()->LoadNamed(name), object); | 1378 old_value = NewNode(javascript()->LoadNamed(name), object); |
| 1409 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1379 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
| 1410 stack_depth = 1; | 1380 stack_depth = 1; |
| 1411 break; | 1381 break; |
| 1412 } | 1382 } |
| 1413 case KEYED_PROPERTY: { | 1383 case KEYED_PROPERTY: { |
| 1414 VisitForValue(property->obj()); | 1384 VisitForValue(property->obj()); |
| 1415 VisitForValue(property->key()); | 1385 VisitForValue(property->key()); |
| 1416 Node* key = environment()->Top(); | 1386 Node* key = environment()->Top(); |
| 1417 Node* object = environment()->Peek(1); | 1387 Node* object = environment()->Peek(1); |
| 1418 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1388 old_value = NewNode(javascript()->LoadProperty(), object, key); |
| 1419 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1389 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
| 1420 stack_depth = 2; | 1390 stack_depth = 2; |
| 1421 break; | 1391 break; |
| 1422 } | 1392 } |
| 1423 } | 1393 } |
| 1424 | 1394 |
| 1425 // Convert old value into a number. | 1395 // Convert old value into a number. |
| 1426 old_value = NewNode(javascript()->ToNumber(), old_value); | 1396 old_value = NewNode(javascript()->ToNumber(), old_value); |
| 1427 | 1397 |
| 1428 // Save result for postfix expressions at correct stack depth. | 1398 // Save result for postfix expressions at correct stack depth. |
| 1429 if (is_postfix) environment()->Poke(stack_depth, old_value); | 1399 if (is_postfix) environment()->Poke(stack_depth, old_value); |
| 1430 | 1400 |
| 1431 // Create node to perform +1/-1 operation. | 1401 // Create node to perform +1/-1 operation. |
| 1432 Node* value = | 1402 Node* value = |
| 1433 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 1403 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); |
| 1434 // TODO(jarin) Insert proper bailout id here (will need to change | 1404 // TODO(jarin) Insert proper bailout id here (will need to change |
| 1435 // full code generator). | 1405 // full code generator). |
| 1436 BuildLazyBailout(value, BailoutId::None()); | 1406 PrepareFrameState(value, BailoutId::None()); |
| 1437 | 1407 |
| 1438 // Store the value. | 1408 // Store the value. |
| 1439 switch (assign_type) { | 1409 switch (assign_type) { |
| 1440 case VARIABLE: { | 1410 case VARIABLE: { |
| 1441 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 1411 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
| 1442 BuildVariableAssignment(variable, value, expr->op(), | 1412 BuildVariableAssignment(variable, value, expr->op(), |
| 1443 expr->AssignmentId()); | 1413 expr->AssignmentId()); |
| 1444 break; | 1414 break; |
| 1445 } | 1415 } |
| 1446 case NAMED_PROPERTY: { | 1416 case NAMED_PROPERTY: { |
| 1447 Node* object = environment()->Pop(); | 1417 Node* object = environment()->Pop(); |
| 1448 PrintableUnique<Name> name = | 1418 PrintableUnique<Name> name = |
| 1449 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1419 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
| 1450 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1420 Node* store = NewNode(javascript()->StoreNamed(name), object, value); |
| 1451 BuildLazyBailout(store, expr->AssignmentId()); | 1421 PrepareFrameState(store, expr->AssignmentId()); |
| 1452 break; | 1422 break; |
| 1453 } | 1423 } |
| 1454 case KEYED_PROPERTY: { | 1424 case KEYED_PROPERTY: { |
| 1455 Node* key = environment()->Pop(); | 1425 Node* key = environment()->Pop(); |
| 1456 Node* object = environment()->Pop(); | 1426 Node* object = environment()->Pop(); |
| 1457 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1427 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); |
| 1458 BuildLazyBailout(store, expr->AssignmentId()); | 1428 PrepareFrameState(store, expr->AssignmentId()); |
| 1459 break; | 1429 break; |
| 1460 } | 1430 } |
| 1461 } | 1431 } |
| 1462 | 1432 |
| 1463 // Restore old value for postfix expressions. | 1433 // Restore old value for postfix expressions. |
| 1464 if (is_postfix) value = environment()->Pop(); | 1434 if (is_postfix) value = environment()->Pop(); |
| 1465 | 1435 |
| 1466 ast_context()->ProduceValue(value); | 1436 ast_context()->ProduceValue(value); |
| 1467 } | 1437 } |
| 1468 | 1438 |
| 1469 | 1439 |
| 1470 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 1440 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| 1471 switch (expr->op()) { | 1441 switch (expr->op()) { |
| 1472 case Token::COMMA: | 1442 case Token::COMMA: |
| 1473 return VisitComma(expr); | 1443 return VisitComma(expr); |
| 1474 case Token::OR: | 1444 case Token::OR: |
| 1475 case Token::AND: | 1445 case Token::AND: |
| 1476 return VisitLogicalExpression(expr); | 1446 return VisitLogicalExpression(expr); |
| 1477 default: { | 1447 default: { |
| 1478 VisitForValue(expr->left()); | 1448 VisitForValue(expr->left()); |
| 1479 VisitForValue(expr->right()); | 1449 VisitForValue(expr->right()); |
| 1480 Node* right = environment()->Pop(); | 1450 Node* right = environment()->Pop(); |
| 1481 Node* left = environment()->Pop(); | 1451 Node* left = environment()->Pop(); |
| 1482 Node* value = BuildBinaryOp(left, right, expr->op()); | 1452 Node* value = BuildBinaryOp(left, right, expr->op()); |
| 1483 ast_context()->ProduceValueWithLazyBailout(value); | 1453 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1454 ast_context()->ProduceValue(value); |
| 1484 } | 1455 } |
| 1485 } | 1456 } |
| 1486 } | 1457 } |
| 1487 | 1458 |
| 1488 | 1459 |
| 1489 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 1460 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 1490 Operator* op; | 1461 Operator* op; |
| 1491 switch (expr->op()) { | 1462 switch (expr->op()) { |
| 1492 case Token::EQ: | 1463 case Token::EQ: |
| 1493 op = javascript()->Equal(); | 1464 op = javascript()->Equal(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1521 break; | 1492 break; |
| 1522 default: | 1493 default: |
| 1523 op = NULL; | 1494 op = NULL; |
| 1524 UNREACHABLE(); | 1495 UNREACHABLE(); |
| 1525 } | 1496 } |
| 1526 VisitForValue(expr->left()); | 1497 VisitForValue(expr->left()); |
| 1527 VisitForValue(expr->right()); | 1498 VisitForValue(expr->right()); |
| 1528 Node* right = environment()->Pop(); | 1499 Node* right = environment()->Pop(); |
| 1529 Node* left = environment()->Pop(); | 1500 Node* left = environment()->Pop(); |
| 1530 Node* value = NewNode(op, left, right); | 1501 Node* value = NewNode(op, left, right); |
| 1502 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1531 ast_context()->ProduceValue(value); | 1503 ast_context()->ProduceValue(value); |
| 1532 | |
| 1533 BuildLazyBailout(value, expr->id()); | |
| 1534 } | 1504 } |
| 1535 | 1505 |
| 1536 | 1506 |
| 1537 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 1507 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 1538 Node* value = GetFunctionClosure(); | 1508 Node* value = GetFunctionClosure(); |
| 1539 ast_context()->ProduceValue(value); | 1509 ast_context()->ProduceValue(value); |
| 1540 } | 1510 } |
| 1541 | 1511 |
| 1542 | 1512 |
| 1543 void AstGraphBuilder::VisitSuperReference(SuperReference* expr) { | 1513 void AstGraphBuilder::VisitSuperReference(SuperReference* expr) { |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1758 ContextualMode contextual_mode) { | 1728 ContextualMode contextual_mode) { |
| 1759 Node* the_hole = jsgraph()->TheHoleConstant(); | 1729 Node* the_hole = jsgraph()->TheHoleConstant(); |
| 1760 VariableMode mode = variable->mode(); | 1730 VariableMode mode = variable->mode(); |
| 1761 switch (variable->location()) { | 1731 switch (variable->location()) { |
| 1762 case Variable::UNALLOCATED: { | 1732 case Variable::UNALLOCATED: { |
| 1763 // Global var, const, or let variable. | 1733 // Global var, const, or let variable. |
| 1764 Node* global = BuildLoadGlobalObject(); | 1734 Node* global = BuildLoadGlobalObject(); |
| 1765 PrintableUnique<Name> name = MakeUnique(variable->name()); | 1735 PrintableUnique<Name> name = MakeUnique(variable->name()); |
| 1766 Operator* op = javascript()->LoadNamed(name, contextual_mode); | 1736 Operator* op = javascript()->LoadNamed(name, contextual_mode); |
| 1767 Node* node = NewNode(op, global); | 1737 Node* node = NewNode(op, global); |
| 1768 BuildLazyBailoutWithPushedNode(node, bailout_id); | 1738 PrepareFrameState(node, bailout_id, PUSH_OUTPUT); |
| 1769 return node; | 1739 return node; |
| 1770 } | 1740 } |
| 1771 case Variable::PARAMETER: | 1741 case Variable::PARAMETER: |
| 1772 case Variable::LOCAL: { | 1742 case Variable::LOCAL: { |
| 1773 // Local var, const, or let variable. | 1743 // Local var, const, or let variable. |
| 1774 Node* value = environment()->Lookup(variable); | 1744 Node* value = environment()->Lookup(variable); |
| 1775 if (mode == CONST_LEGACY) { | 1745 if (mode == CONST_LEGACY) { |
| 1776 // Perform check for uninitialized legacy const variables. | 1746 // Perform check for uninitialized legacy const variables. |
| 1777 if (value->op() == the_hole->op()) { | 1747 if (value->op() == the_hole->op()) { |
| 1778 value = jsgraph()->UndefinedConstant(); | 1748 value = jsgraph()->UndefinedConstant(); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1859 BailoutId bailout_id) { | 1829 BailoutId bailout_id) { |
| 1860 Node* the_hole = jsgraph()->TheHoleConstant(); | 1830 Node* the_hole = jsgraph()->TheHoleConstant(); |
| 1861 VariableMode mode = variable->mode(); | 1831 VariableMode mode = variable->mode(); |
| 1862 switch (variable->location()) { | 1832 switch (variable->location()) { |
| 1863 case Variable::UNALLOCATED: { | 1833 case Variable::UNALLOCATED: { |
| 1864 // Global var, const, or let variable. | 1834 // Global var, const, or let variable. |
| 1865 Node* global = BuildLoadGlobalObject(); | 1835 Node* global = BuildLoadGlobalObject(); |
| 1866 PrintableUnique<Name> name = MakeUnique(variable->name()); | 1836 PrintableUnique<Name> name = MakeUnique(variable->name()); |
| 1867 Operator* op = javascript()->StoreNamed(name); | 1837 Operator* op = javascript()->StoreNamed(name); |
| 1868 Node* store = NewNode(op, global, value); | 1838 Node* store = NewNode(op, global, value); |
| 1869 BuildLazyBailout(store, bailout_id); | 1839 PrepareFrameState(store, bailout_id); |
| 1870 return store; | 1840 return store; |
| 1871 } | 1841 } |
| 1872 case Variable::PARAMETER: | 1842 case Variable::PARAMETER: |
| 1873 case Variable::LOCAL: | 1843 case Variable::LOCAL: |
| 1874 // Local var, const, or let variable. | 1844 // Local var, const, or let variable. |
| 1875 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 1845 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
| 1876 // Perform an initialization check for legacy const variables. | 1846 // Perform an initialization check for legacy const variables. |
| 1877 Node* current = environment()->Lookup(variable); | 1847 Node* current = environment()->Lookup(variable); |
| 1878 if (current->op() != the_hole->op()) { | 1848 if (current->op() != the_hole->op()) { |
| 1879 value = BuildHoleCheckSilent(current, value, current); | 1849 value = BuildHoleCheckSilent(current, value, current); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 js_op = javascript()->Modulus(); | 1981 js_op = javascript()->Modulus(); |
| 2012 break; | 1982 break; |
| 2013 default: | 1983 default: |
| 2014 UNREACHABLE(); | 1984 UNREACHABLE(); |
| 2015 js_op = NULL; | 1985 js_op = NULL; |
| 2016 } | 1986 } |
| 2017 return NewNode(js_op, left, right); | 1987 return NewNode(js_op, left, right); |
| 2018 } | 1988 } |
| 2019 | 1989 |
| 2020 | 1990 |
| 2021 void AstGraphBuilder::BuildLazyBailout(Node* node, BailoutId ast_id) { | 1991 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, |
| 1992 OutputFrameStateCombine combine) { |
| 1993 if (OperatorProperties::HasFrameStateInput(node->op())) { |
| 1994 int frame_state_index = NodeProperties::GetFrameStateIndex(node); |
| 1995 |
| 1996 DCHECK(node->InputAt(frame_state_index)->op()->opcode() == IrOpcode::kDead); |
| 1997 |
| 1998 Node* frame_state_node = environment()->Checkpoint(ast_id); |
| 1999 node->ReplaceInput(frame_state_index, frame_state_node); |
| 2000 } |
| 2001 |
| 2022 if (OperatorProperties::CanLazilyDeoptimize(node->op())) { | 2002 if (OperatorProperties::CanLazilyDeoptimize(node->op())) { |
| 2023 // The deopting node should have an outgoing control dependency. | 2003 // The deopting node should have an outgoing control dependency. |
| 2024 DCHECK(environment()->GetControlDependency() == node); | 2004 DCHECK(environment()->GetControlDependency() == node); |
| 2025 | 2005 |
| 2026 StructuredGraphBuilder::Environment* continuation_env = environment(); | 2006 StructuredGraphBuilder::Environment* continuation_env = environment(); |
| 2027 // Create environment for the deoptimization block, and build the block. | 2007 // Create environment for the deoptimization block, and build the block. |
| 2028 StructuredGraphBuilder::Environment* deopt_env = | 2008 StructuredGraphBuilder::Environment* deopt_env = |
| 2029 CopyEnvironment(continuation_env); | 2009 CopyEnvironment(continuation_env); |
| 2030 set_environment(deopt_env); | 2010 set_environment(deopt_env); |
| 2031 | 2011 |
| 2012 if (combine == PUSH_OUTPUT) { |
| 2013 environment()->Push(node); |
| 2014 } |
| 2015 |
| 2032 NewNode(common()->LazyDeoptimization()); | 2016 NewNode(common()->LazyDeoptimization()); |
| 2033 | 2017 |
| 2034 // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty | 2018 // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty |
| 2035 // deopt block and make sure there is no patch entry for this (so | 2019 // deopt block and make sure there is no patch entry for this (so |
| 2036 // that the deoptimizer dies when trying to deoptimize here). | 2020 // that the deoptimizer dies when trying to deoptimize here). |
| 2037 | |
| 2038 Node* state_node = environment()->Checkpoint(ast_id); | 2021 Node* state_node = environment()->Checkpoint(ast_id); |
| 2039 | |
| 2040 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); | 2022 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); |
| 2041 | |
| 2042 UpdateControlDependencyToLeaveFunction(deoptimize_node); | 2023 UpdateControlDependencyToLeaveFunction(deoptimize_node); |
| 2043 | 2024 |
| 2044 // Continue with the original environment. | 2025 // Continue with the original environment. |
| 2045 set_environment(continuation_env); | 2026 set_environment(continuation_env); |
| 2046 | |
| 2047 NewNode(common()->Continuation()); | 2027 NewNode(common()->Continuation()); |
| 2048 } | 2028 } |
| 2049 } | 2029 } |
| 2050 | 2030 |
| 2051 | |
| 2052 void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node, | |
| 2053 BailoutId ast_id) { | |
| 2054 environment()->Push(node); | |
| 2055 BuildLazyBailout(node, ast_id); | |
| 2056 environment()->Pop(); | |
| 2057 } | |
| 2058 } | 2031 } |
| 2059 } | 2032 } |
| 2060 } // namespace v8::internal::compiler | 2033 } // namespace v8::internal::compiler |
| OLD | NEW |