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

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