Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 492203002: Initial support for debugger frame state in Turbofan. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Another attempt to fix Win64 Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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(&parameters_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698