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

Side by Side Diff: src/full-codegen/full-codegen.cc

Issue 1706283002: [fullcodegen] Implement operand stack depth tracking. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off verification. Created 4 years, 10 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
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/full-codegen/full-codegen.h" 5 #include "src/full-codegen/full-codegen.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/ast/ast-numbering.h" 8 #include "src/ast/ast-numbering.h"
9 #include "src/ast/prettyprinter.h" 9 #include "src/ast/prettyprinter.h"
10 #include "src/ast/scopeinfo.h" 10 #include "src/ast/scopeinfo.h"
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 void FullCodeGenerator::EffectContext::Plug(Register reg) const { 265 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
266 } 266 }
267 267
268 268
269 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 269 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
270 __ Move(result_register(), reg); 270 __ Move(result_register(), reg);
271 } 271 }
272 272
273 273
274 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { 274 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
275 __ Push(reg); 275 codegen()->PushOperand(reg);
276 } 276 }
277 277
278 278
279 void FullCodeGenerator::TestContext::Plug(Register reg) const { 279 void FullCodeGenerator::TestContext::Plug(Register reg) const {
280 // For simplicity we always test the accumulator register. 280 // For simplicity we always test the accumulator register.
281 __ Move(result_register(), reg); 281 __ Move(result_register(), reg);
282 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 282 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
283 codegen()->DoTest(this); 283 codegen()->DoTest(this);
284 } 284 }
285 285
286 286
287 void FullCodeGenerator::EffectContext::Plug(bool flag) const {} 287 void FullCodeGenerator::EffectContext::Plug(bool flag) const {}
288 288
289 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
290 Register reg) const {
291 DCHECK(count > 0);
292 codegen()->DropOperands(count);
293 }
294
295 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
296 int count, Register reg) const {
297 DCHECK(count > 0);
298 codegen()->DropOperands(count);
299 __ Move(result_register(), reg);
300 }
301
302 void FullCodeGenerator::TestContext::DropAndPlug(int count,
303 Register reg) const {
304 DCHECK(count > 0);
305 // For simplicity we always test the accumulator register.
306 codegen()->DropOperands(count);
307 __ Move(result_register(), reg);
308 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
309 codegen()->DoTest(this);
310 }
289 311
290 void FullCodeGenerator::EffectContext::PlugTOS() const { 312 void FullCodeGenerator::EffectContext::PlugTOS() const {
291 __ Drop(1); 313 codegen()->DropOperands(1);
292 } 314 }
293 315
294 316
295 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 317 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
296 __ Pop(result_register()); 318 codegen()->PopOperand(result_register());
297 } 319 }
298 320
299 321
300 void FullCodeGenerator::StackValueContext::PlugTOS() const { 322 void FullCodeGenerator::StackValueContext::PlugTOS() const {
301 } 323 }
302 324
303 325
304 void FullCodeGenerator::TestContext::PlugTOS() const { 326 void FullCodeGenerator::TestContext::PlugTOS() const {
305 // For simplicity we always test the accumulator register. 327 // For simplicity we always test the accumulator register.
306 __ Pop(result_register()); 328 codegen()->PopOperand(result_register());
307 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 329 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
308 codegen()->DoTest(this); 330 codegen()->DoTest(this);
309 } 331 }
310 332
311 333
312 void FullCodeGenerator::EffectContext::PrepareTest( 334 void FullCodeGenerator::EffectContext::PrepareTest(
313 Label* materialize_true, 335 Label* materialize_true,
314 Label* materialize_false, 336 Label* materialize_false,
315 Label** if_true, 337 Label** if_true,
316 Label** if_false, 338 Label** if_false,
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 } 448 }
427 449
428 450
429 int FullCodeGenerator::DeclareGlobalsFlags() { 451 int FullCodeGenerator::DeclareGlobalsFlags() {
430 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); 452 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode()));
431 return DeclareGlobalsEvalFlag::encode(is_eval()) | 453 return DeclareGlobalsEvalFlag::encode(is_eval()) |
432 DeclareGlobalsNativeFlag::encode(is_native()) | 454 DeclareGlobalsNativeFlag::encode(is_native()) |
433 DeclareGlobalsLanguageMode::encode(language_mode()); 455 DeclareGlobalsLanguageMode::encode(language_mode());
434 } 456 }
435 457
458 void FullCodeGenerator::PushOperand(Handle<Object> handle) {
459 OperandStackDepthIncrement(1);
460 __ Push(handle);
461 }
462
463 void FullCodeGenerator::PushOperand(Smi* smi) {
464 OperandStackDepthIncrement(1);
465 __ Push(smi);
466 }
467
468 void FullCodeGenerator::PushOperand(Register reg) {
469 OperandStackDepthIncrement(1);
470 __ Push(reg);
471 }
472
473 void FullCodeGenerator::PopOperand(Register reg) {
474 OperandStackDepthDecrement(1);
475 __ Pop(reg);
476 }
477
478 void FullCodeGenerator::DropOperands(int count) {
479 OperandStackDepthDecrement(count);
480 __ Drop(count);
481 }
482
483 void FullCodeGenerator::CallRuntimeWithOperands(Runtime::FunctionId id) {
484 OperandStackDepthDecrement(Runtime::FunctionForId(id)->nargs);
485 __ CallRuntime(id);
486 }
487
488 void FullCodeGenerator::OperandStackDepthIncrement(int count) {
489 DCHECK_GE(count, 0);
490 DCHECK_GE(operand_stack_depth_, 0);
491 operand_stack_depth_ += count;
492 }
493
494 void FullCodeGenerator::OperandStackDepthDecrement(int count) {
495 DCHECK_GE(count, 0);
496 DCHECK_GE(operand_stack_depth_, count);
497 operand_stack_depth_ -= count;
498 }
436 499
437 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { 500 void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
438 // Load the arguments on the stack and call the stub. 501 // Load the arguments on the stack and call the stub.
439 SubStringStub stub(isolate()); 502 SubStringStub stub(isolate());
440 ZoneList<Expression*>* args = expr->arguments(); 503 ZoneList<Expression*>* args = expr->arguments();
441 DCHECK(args->length() == 3); 504 DCHECK(args->length() == 3);
442 VisitForStackValue(args->at(0)); 505 VisitForStackValue(args->at(0));
443 VisitForStackValue(args->at(1)); 506 VisitForStackValue(args->at(1));
444 VisitForStackValue(args->at(2)); 507 VisitForStackValue(args->at(2));
445 __ CallStub(&stub); 508 __ CallStub(&stub);
509 OperandStackDepthDecrement(3);
446 context()->Plug(result_register()); 510 context()->Plug(result_register());
447 } 511 }
448 512
449 513
450 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { 514 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
451 // Load the arguments on the stack and call the stub. 515 // Load the arguments on the stack and call the stub.
452 RegExpExecStub stub(isolate()); 516 RegExpExecStub stub(isolate());
453 ZoneList<Expression*>* args = expr->arguments(); 517 ZoneList<Expression*>* args = expr->arguments();
454 DCHECK(args->length() == 4); 518 DCHECK(args->length() == 4);
455 VisitForStackValue(args->at(0)); 519 VisitForStackValue(args->at(0));
456 VisitForStackValue(args->at(1)); 520 VisitForStackValue(args->at(1));
457 VisitForStackValue(args->at(2)); 521 VisitForStackValue(args->at(2));
458 VisitForStackValue(args->at(3)); 522 VisitForStackValue(args->at(3));
459 __ CallStub(&stub); 523 __ CallStub(&stub);
524 OperandStackDepthDecrement(4);
460 context()->Plug(result_register()); 525 context()->Plug(result_register());
461 } 526 }
462 527
463 528
464 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { 529 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
465 // Load the arguments on the stack and call the runtime function. 530 // Load the arguments on the stack and call the runtime function.
531 MathPowStub stub(isolate(), MathPowStub::ON_STACK);
466 ZoneList<Expression*>* args = expr->arguments(); 532 ZoneList<Expression*>* args = expr->arguments();
467 DCHECK(args->length() == 2); 533 DCHECK(args->length() == 2);
468 VisitForStackValue(args->at(0)); 534 VisitForStackValue(args->at(0));
469 VisitForStackValue(args->at(1)); 535 VisitForStackValue(args->at(1));
470
471 MathPowStub stub(isolate(), MathPowStub::ON_STACK);
472 __ CallStub(&stub); 536 __ CallStub(&stub);
537 OperandStackDepthDecrement(2);
473 context()->Plug(result_register()); 538 context()->Plug(result_register());
474 } 539 }
475 540
476 541
477 void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr, 542 void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr,
478 const Callable& callable) { 543 const Callable& callable) {
479 ZoneList<Expression*>* args = expr->arguments(); 544 ZoneList<Expression*>* args = expr->arguments();
480 int param_count = callable.descriptor().GetRegisterParameterCount(); 545 int param_count = callable.descriptor().GetRegisterParameterCount();
481 DCHECK_EQ(args->length(), param_count); 546 DCHECK_EQ(args->length(), param_count);
482 547
483 if (param_count > 0) { 548 if (param_count > 0) {
484 int last = param_count - 1; 549 int last = param_count - 1;
485 // Put all but last arguments on stack. 550 // Put all but last arguments on stack.
486 for (int i = 0; i < last; i++) { 551 for (int i = 0; i < last; i++) {
487 VisitForStackValue(args->at(i)); 552 VisitForStackValue(args->at(i));
488 } 553 }
489 // The last argument goes to the accumulator. 554 // The last argument goes to the accumulator.
490 VisitForAccumulatorValue(args->at(last)); 555 VisitForAccumulatorValue(args->at(last));
491 556
492 // Move the arguments to the registers, as required by the stub. 557 // Move the arguments to the registers, as required by the stub.
493 __ Move(callable.descriptor().GetRegisterParameter(last), 558 __ Move(callable.descriptor().GetRegisterParameter(last),
494 result_register()); 559 result_register());
495 for (int i = last; i-- > 0;) { 560 for (int i = last; i-- > 0;) {
496 __ Pop(callable.descriptor().GetRegisterParameter(i)); 561 PopOperand(callable.descriptor().GetRegisterParameter(i));
497 } 562 }
498 } 563 }
499 __ Call(callable.code(), RelocInfo::CODE_TARGET); 564 __ Call(callable.code(), RelocInfo::CODE_TARGET);
500 context()->Plug(result_register()); 565 context()->Plug(result_register());
501 } 566 }
502 567
503 568
504 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { 569 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
505 EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate())); 570 EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate()));
506 } 571 }
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 DCHECK_EQ(0, context_length); 1001 DCHECK_EQ(0, context_length);
937 current->AsTryFinally()->deferred_commands()->RecordReturn(); 1002 current->AsTryFinally()->deferred_commands()->RecordReturn();
938 return; 1003 return;
939 } 1004 }
940 current = current->Exit(&stack_depth, &context_length); 1005 current = current->Exit(&stack_depth, &context_length);
941 } 1006 }
942 __ Drop(stack_depth); 1007 __ Drop(stack_depth);
943 EmitReturnSequence(); 1008 EmitReturnSequence();
944 } 1009 }
945 1010
1011 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
1012 // Stack: receiver, home_object
1013 SetExpressionPosition(prop);
1014 Literal* key = prop->key()->AsLiteral();
1015 DCHECK(!key->value()->IsSmi());
1016 DCHECK(prop->IsSuperAccess());
1017
1018 PushOperand(key->value());
1019 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
1020 }
1021
1022 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1023 SetExpressionPosition(prop);
1024 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
1025 __ Move(LoadDescriptor::SlotRegister(),
1026 SmiFromSlot(prop->PropertyFeedbackSlot()));
1027 CallIC(ic);
1028 }
1029
1030 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
1031 // Stack: receiver, home_object, key.
1032 SetExpressionPosition(prop);
1033 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
1034 }
946 1035
947 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, 1036 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
948 BailoutId bailout_id) { 1037 BailoutId bailout_id) {
949 VisitForStackValue(property->key()); 1038 VisitForStackValue(property->key());
950 __ CallRuntime(Runtime::kToName); 1039 CallRuntimeWithOperands(Runtime::kToName);
951 PrepareForBailoutForId(bailout_id, NO_REGISTERS); 1040 PrepareForBailoutForId(bailout_id, NO_REGISTERS);
952 __ Push(result_register()); 1041 PushOperand(result_register());
953 } 1042 }
954 1043
955 1044
956 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1045 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
957 Comment cmnt(masm_, "[ ReturnStatement"); 1046 Comment cmnt(masm_, "[ ReturnStatement");
958 SetStatementPosition(stmt); 1047 SetStatementPosition(stmt);
959 Expression* expr = stmt->expression(); 1048 Expression* expr = stmt->expression();
960 VisitForAccumulatorValue(expr); 1049 VisitForAccumulatorValue(expr);
961 EmitUnwindAndReturn(); 1050 EmitUnwindAndReturn();
962 } 1051 }
963 1052
964 1053
965 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 1054 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
966 Comment cmnt(masm_, "[ WithStatement"); 1055 Comment cmnt(masm_, "[ WithStatement");
967 SetStatementPosition(stmt); 1056 SetStatementPosition(stmt);
968 1057
969 VisitForAccumulatorValue(stmt->expression()); 1058 VisitForAccumulatorValue(stmt->expression());
970 Callable callable = CodeFactory::ToObject(isolate()); 1059 Callable callable = CodeFactory::ToObject(isolate());
971 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); 1060 __ Move(callable.descriptor().GetRegisterParameter(0), result_register());
972 __ Call(callable.code(), RelocInfo::CODE_TARGET); 1061 __ Call(callable.code(), RelocInfo::CODE_TARGET);
973 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); 1062 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS);
974 __ Push(result_register()); 1063 PushOperand(result_register());
975 PushFunctionArgumentForContextAllocation(); 1064 PushFunctionArgumentForContextAllocation();
976 __ CallRuntime(Runtime::kPushWithContext); 1065 CallRuntimeWithOperands(Runtime::kPushWithContext);
977 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1066 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
978 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 1067 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
979 1068
980 Scope* saved_scope = scope(); 1069 Scope* saved_scope = scope();
981 scope_ = stmt->scope(); 1070 scope_ = stmt->scope();
982 { WithOrCatch body(this); 1071 { WithOrCatch body(this);
983 Visit(stmt->statement()); 1072 Visit(stmt->statement());
984 } 1073 }
985 scope_ = saved_scope; 1074 scope_ = saved_scope;
986 1075
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 // result register. 1248 // result register.
1160 1249
1161 Label try_entry, handler_entry, exit; 1250 Label try_entry, handler_entry, exit;
1162 __ jmp(&try_entry); 1251 __ jmp(&try_entry);
1163 __ bind(&handler_entry); 1252 __ bind(&handler_entry);
1164 ClearPendingMessage(); 1253 ClearPendingMessage();
1165 1254
1166 // Exception handler code, the exception is in the result register. 1255 // Exception handler code, the exception is in the result register.
1167 // Extend the context before executing the catch block. 1256 // Extend the context before executing the catch block.
1168 { Comment cmnt(masm_, "[ Extend catch context"); 1257 { Comment cmnt(masm_, "[ Extend catch context");
1169 __ Push(stmt->variable()->name()); 1258 PushOperand(stmt->variable()->name());
1170 __ Push(result_register()); 1259 PushOperand(result_register());
1171 PushFunctionArgumentForContextAllocation(); 1260 PushFunctionArgumentForContextAllocation();
1172 __ CallRuntime(Runtime::kPushCatchContext); 1261 CallRuntimeWithOperands(Runtime::kPushCatchContext);
1173 StoreToFrameField(StandardFrameConstants::kContextOffset, 1262 StoreToFrameField(StandardFrameConstants::kContextOffset,
1174 context_register()); 1263 context_register());
1175 } 1264 }
1176 1265
1177 Scope* saved_scope = scope(); 1266 Scope* saved_scope = scope();
1178 scope_ = stmt->scope(); 1267 scope_ = stmt->scope();
1179 DCHECK(scope_->declarations()->is_empty()); 1268 DCHECK(scope_->declarations()->is_empty());
1180 { WithOrCatch catch_body(this); 1269 { WithOrCatch catch_body(this);
1181 Visit(stmt->catch_block()); 1270 Visit(stmt->catch_block());
1182 } 1271 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 // value in the result register with one that's safe for GC because the 1339 // value in the result register with one that's safe for GC because the
1251 // finally block will unconditionally preserve the result register on the 1340 // finally block will unconditionally preserve the result register on the
1252 // stack. 1341 // stack.
1253 ClearAccumulator(); 1342 ClearAccumulator();
1254 deferred.EmitFallThrough(); 1343 deferred.EmitFallThrough();
1255 // Fall through to the finally block. 1344 // Fall through to the finally block.
1256 1345
1257 // Finally block implementation. 1346 // Finally block implementation.
1258 __ bind(&finally_entry); 1347 __ bind(&finally_entry);
1259 Comment cmnt_finally(masm(), "[ Finally block"); 1348 Comment cmnt_finally(masm(), "[ Finally block");
1349 OperandStackDepthIncrement(2); // Token and accumulator are on stack.
1260 EnterFinallyBlock(); 1350 EnterFinallyBlock();
1261 { 1351 {
1262 Finally finally_body(this); 1352 Finally finally_body(this);
1263 Visit(stmt->finally_block()); 1353 Visit(stmt->finally_block());
1264 } 1354 }
1265 ExitFinallyBlock(); // Return to the calling code. 1355 ExitFinallyBlock();
1356 OperandStackDepthDecrement(2); // Token and accumulator were on stack.
1266 1357
1267 { 1358 {
1268 Comment cmnt_deferred(masm(), "[ Post-finally dispatch"); 1359 Comment cmnt_deferred(masm(), "[ Post-finally dispatch");
1269 deferred.EmitCommands(); 1360 deferred.EmitCommands(); // Return to the calling code.
1270 } 1361 }
1271 } 1362 }
1272 1363
1273 1364
1274 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1365 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1275 Comment cmnt(masm_, "[ DebuggerStatement"); 1366 Comment cmnt(masm_, "[ DebuggerStatement");
1276 SetStatementPosition(stmt); 1367 SetStatementPosition(stmt);
1277 1368
1278 __ DebugBreak(); 1369 __ DebugBreak();
1279 // Ignore the return value. 1370 // Ignore the return value.
1280 1371
1281 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); 1372 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS);
1282 } 1373 }
1283 1374
1284 1375
1285 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { 1376 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) {
1286 UNREACHABLE(); 1377 UNREACHABLE();
1287 } 1378 }
1288 1379
1289 1380
1290 void FullCodeGenerator::VisitConditional(Conditional* expr) { 1381 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1291 Comment cmnt(masm_, "[ Conditional"); 1382 Comment cmnt(masm_, "[ Conditional");
1292 Label true_case, false_case, done; 1383 Label true_case, false_case, done;
1293 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1384 VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1294 1385
1386 int original_stack_depth = operand_stack_depth_;
1295 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1387 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
1296 __ bind(&true_case); 1388 __ bind(&true_case);
1297 SetExpressionPosition(expr->then_expression()); 1389 SetExpressionPosition(expr->then_expression());
1298 if (context()->IsTest()) { 1390 if (context()->IsTest()) {
1299 const TestContext* for_test = TestContext::cast(context()); 1391 const TestContext* for_test = TestContext::cast(context());
1300 VisitForControl(expr->then_expression(), 1392 VisitForControl(expr->then_expression(),
1301 for_test->true_label(), 1393 for_test->true_label(),
1302 for_test->false_label(), 1394 for_test->false_label(),
1303 NULL); 1395 NULL);
1304 } else { 1396 } else {
1305 VisitInDuplicateContext(expr->then_expression()); 1397 VisitInDuplicateContext(expr->then_expression());
1306 __ jmp(&done); 1398 __ jmp(&done);
1307 } 1399 }
1308 1400
1401 operand_stack_depth_ = original_stack_depth;
1309 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1402 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1310 __ bind(&false_case); 1403 __ bind(&false_case);
1311 SetExpressionPosition(expr->else_expression()); 1404 SetExpressionPosition(expr->else_expression());
1312 VisitInDuplicateContext(expr->else_expression()); 1405 VisitInDuplicateContext(expr->else_expression());
1313 // If control flow falls through Visit, merge it with true case here. 1406 // If control flow falls through Visit, merge it with true case here.
1314 if (!context()->IsTest()) { 1407 if (!context()->IsTest()) {
1315 __ bind(&done); 1408 __ bind(&done);
1316 } 1409 }
1317 } 1410 }
1318 1411
(...skipping 21 matching lines...) Expand all
1340 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { 1433 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
1341 Comment cmnt(masm_, "[ ClassLiteral"); 1434 Comment cmnt(masm_, "[ ClassLiteral");
1342 1435
1343 { 1436 {
1344 EnterBlockScopeIfNeeded block_scope_state( 1437 EnterBlockScopeIfNeeded block_scope_state(
1345 this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId()); 1438 this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId());
1346 1439
1347 if (lit->extends() != NULL) { 1440 if (lit->extends() != NULL) {
1348 VisitForStackValue(lit->extends()); 1441 VisitForStackValue(lit->extends());
1349 } else { 1442 } else {
1350 __ Push(isolate()->factory()->the_hole_value()); 1443 PushOperand(isolate()->factory()->the_hole_value());
1351 } 1444 }
1352 1445
1353 VisitForStackValue(lit->constructor()); 1446 VisitForStackValue(lit->constructor());
1354 1447
1355 __ Push(Smi::FromInt(lit->start_position())); 1448 PushOperand(Smi::FromInt(lit->start_position()));
1356 __ Push(Smi::FromInt(lit->end_position())); 1449 PushOperand(Smi::FromInt(lit->end_position()));
1357 1450
1358 __ CallRuntime(Runtime::kDefineClass); 1451 CallRuntimeWithOperands(Runtime::kDefineClass);
1359 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); 1452 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG);
1360 __ Push(result_register()); 1453 PushOperand(result_register());
1361 1454
1362 // Load the "prototype" from the constructor. 1455 // Load the "prototype" from the constructor.
1363 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); 1456 __ Move(LoadDescriptor::ReceiverRegister(), result_register());
1364 __ LoadRoot(LoadDescriptor::NameRegister(), 1457 __ LoadRoot(LoadDescriptor::NameRegister(),
1365 Heap::kprototype_stringRootIndex); 1458 Heap::kprototype_stringRootIndex);
1366 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); 1459 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot()));
1367 CallLoadIC(NOT_INSIDE_TYPEOF); 1460 CallLoadIC(NOT_INSIDE_TYPEOF);
1368 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); 1461 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG);
1369 __ Push(result_register()); 1462 PushOperand(result_register());
1370 1463
1371 EmitClassDefineProperties(lit); 1464 EmitClassDefineProperties(lit);
1372 1465
1373 // Set both the prototype and constructor to have fast properties, and also 1466 // Set both the prototype and constructor to have fast properties, and also
1374 // freeze them in strong mode. 1467 // freeze them in strong mode.
1375 __ CallRuntime(Runtime::kFinalizeClassDefinition); 1468 CallRuntimeWithOperands(Runtime::kFinalizeClassDefinition);
1376 1469
1377 if (lit->class_variable_proxy() != nullptr) { 1470 if (lit->class_variable_proxy() != nullptr) {
1378 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, 1471 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT,
1379 lit->ProxySlot()); 1472 lit->ProxySlot());
1380 } 1473 }
1381 } 1474 }
1382 1475
1383 context()->Plug(result_register()); 1476 context()->Plug(result_register());
1384 } 1477 }
1385 1478
1386 1479
1387 void FullCodeGenerator::VisitNativeFunctionLiteral( 1480 void FullCodeGenerator::VisitNativeFunctionLiteral(
1388 NativeFunctionLiteral* expr) { 1481 NativeFunctionLiteral* expr) {
1389 Comment cmnt(masm_, "[ NativeFunctionLiteral"); 1482 Comment cmnt(masm_, "[ NativeFunctionLiteral");
1390 Handle<SharedFunctionInfo> shared = 1483 Handle<SharedFunctionInfo> shared =
1391 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); 1484 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name());
1392 EmitNewClosure(shared, false); 1485 EmitNewClosure(shared, false);
1393 } 1486 }
1394 1487
1395 1488
1396 void FullCodeGenerator::VisitThrow(Throw* expr) { 1489 void FullCodeGenerator::VisitThrow(Throw* expr) {
1397 Comment cmnt(masm_, "[ Throw"); 1490 Comment cmnt(masm_, "[ Throw");
1398 VisitForStackValue(expr->exception()); 1491 VisitForStackValue(expr->exception());
1399 SetExpressionPosition(expr); 1492 SetExpressionPosition(expr);
1400 __ CallRuntime(Runtime::kThrow); 1493 CallRuntimeWithOperands(Runtime::kThrow);
1401 // Never returns here. 1494 // Never returns here.
1495
1496 // Even though this expression doesn't produce a value, we need to simulate
1497 // plugging of the value context to ensure stack depth tracking is in sync.
1498 if (context()->IsStackValue()) OperandStackDepthIncrement(1);
1402 } 1499 }
1403 1500
1404 1501
1405 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) { 1502 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) {
1406 HandlerTableEntry* entry = &handler_table_[handler_index]; 1503 HandlerTableEntry* entry = &handler_table_[handler_index];
1407 entry->range_start = masm()->pc_offset(); 1504 entry->range_start = masm()->pc_offset();
1408 entry->handler_offset = handler->pos(); 1505 entry->handler_offset = handler->pos();
1409 entry->try_catch_depth = try_catch_depth_; 1506 entry->try_catch_depth = try_catch_depth_;
1507 entry->stack_depth = operand_stack_depth_;
1410 1508
1411 // Determine expression stack depth of try statement. 1509 // We are using the operand stack depth, check for accuracy.
1412 int stack_depth = info_->scope()->num_stack_slots(); // Include stack locals. 1510 EmitOperandStackDepthCheck();
1413 for (NestedStatement* current = nesting_stack_; current != NULL; /*nop*/) {
1414 current = current->AccumulateDepth(&stack_depth);
1415 }
1416 entry->stack_depth = stack_depth;
1417 1511
1418 // Push context onto operand stack. 1512 // Push context onto operand stack.
1419 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); 1513 STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1420 __ Push(context_register()); 1514 PushOperand(context_register());
1421 } 1515 }
1422 1516
1423 1517
1424 void FullCodeGenerator::ExitTryBlock(int handler_index) { 1518 void FullCodeGenerator::ExitTryBlock(int handler_index) {
1425 HandlerTableEntry* entry = &handler_table_[handler_index]; 1519 HandlerTableEntry* entry = &handler_table_[handler_index];
1426 entry->range_end = masm()->pc_offset(); 1520 entry->range_end = masm()->pc_offset();
1427 1521
1428 // Drop context from operand stack. 1522 // Drop context from operand stack.
1429 __ Drop(TryBlockConstant::kElementCount); 1523 DropOperands(TryBlockConstant::kElementCount);
1430 } 1524 }
1431 1525
1432 1526
1433 void FullCodeGenerator::VisitCall(Call* expr) { 1527 void FullCodeGenerator::VisitCall(Call* expr) {
1434 #ifdef DEBUG 1528 #ifdef DEBUG
1435 // We want to verify that RecordJSReturnSite gets called on all paths 1529 // We want to verify that RecordJSReturnSite gets called on all paths
1436 // through this function. Avoid early returns. 1530 // through this function. Avoid early returns.
1437 expr->return_is_recorded_ = false; 1531 expr->return_is_recorded_ = false;
1438 #endif 1532 #endif
1439 1533
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 break; 1566 break;
1473 case Call::KEYED_SUPER_PROPERTY_CALL: 1567 case Call::KEYED_SUPER_PROPERTY_CALL:
1474 EmitKeyedSuperCallWithLoadIC(expr); 1568 EmitKeyedSuperCallWithLoadIC(expr);
1475 break; 1569 break;
1476 case Call::SUPER_CALL: 1570 case Call::SUPER_CALL:
1477 EmitSuperConstructorCall(expr); 1571 EmitSuperConstructorCall(expr);
1478 break; 1572 break;
1479 case Call::OTHER_CALL: 1573 case Call::OTHER_CALL:
1480 // Call to an arbitrary expression not handled specially above. 1574 // Call to an arbitrary expression not handled specially above.
1481 VisitForStackValue(callee); 1575 VisitForStackValue(callee);
1576 OperandStackDepthIncrement(1);
1482 __ PushRoot(Heap::kUndefinedValueRootIndex); 1577 __ PushRoot(Heap::kUndefinedValueRootIndex);
1483 // Emit function call. 1578 // Emit function call.
1484 EmitCall(expr); 1579 EmitCall(expr);
1485 break; 1580 break;
1486 } 1581 }
1487 1582
1488 #ifdef DEBUG 1583 #ifdef DEBUG
1489 // RecordJSReturnSite should have been called. 1584 // RecordJSReturnSite should have been called.
1490 DCHECK(expr->return_is_recorded_); 1585 DCHECK(expr->return_is_recorded_);
1491 #endif 1586 #endif
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 1782
1688 if (scope == NULL) { 1783 if (scope == NULL) {
1689 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); 1784 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
1690 needs_block_context_ = false; 1785 needs_block_context_ = false;
1691 } else { 1786 } else {
1692 needs_block_context_ = scope->NeedsContext(); 1787 needs_block_context_ = scope->NeedsContext();
1693 codegen_->scope_ = scope; 1788 codegen_->scope_ = scope;
1694 { 1789 {
1695 if (needs_block_context_) { 1790 if (needs_block_context_) {
1696 Comment cmnt(masm(), "[ Extend block context"); 1791 Comment cmnt(masm(), "[ Extend block context");
1697 __ Push(scope->GetScopeInfo(codegen->isolate())); 1792 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate()));
1698 codegen_->PushFunctionArgumentForContextAllocation(); 1793 codegen_->PushFunctionArgumentForContextAllocation();
1699 __ CallRuntime(Runtime::kPushBlockContext); 1794 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext);
1700 1795
1701 // Replace the context stored in the frame. 1796 // Replace the context stored in the frame.
1702 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, 1797 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1703 codegen_->context_register()); 1798 codegen_->context_register());
1704 } 1799 }
1705 CHECK_EQ(0, scope->num_stack_slots()); 1800 CHECK_EQ(0, scope->num_stack_slots());
1706 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); 1801 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
1707 } 1802 }
1708 { 1803 {
1709 Comment cmnt(masm(), "[ Declarations"); 1804 Comment cmnt(masm(), "[ Declarations");
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() || 1879 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() ||
1785 var->initializer_position() >= proxy->position(); 1880 var->initializer_position() >= proxy->position();
1786 } 1881 }
1787 1882
1788 1883
1789 #undef __ 1884 #undef __
1790 1885
1791 1886
1792 } // namespace internal 1887 } // namespace internal
1793 } // namespace v8 1888 } // namespace v8
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698