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

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: 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
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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 void FullCodeGenerator::EffectContext::Plug(Register reg) const { 270 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
271 } 271 }
272 272
273 273
274 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 274 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
275 __ Move(result_register(), reg); 275 __ Move(result_register(), reg);
276 } 276 }
277 277
278 278
279 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { 279 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
280 codegen()->OperandStackDepthIncrement(1);
Jarin 2016/02/19 06:52:04 Could not you call codegen()->PushOperand here? (
Michael Starzinger 2016/02/19 09:24:04 Done. Here and below.
280 __ Push(reg); 281 __ Push(reg);
281 } 282 }
282 283
283 284
284 void FullCodeGenerator::TestContext::Plug(Register reg) const { 285 void FullCodeGenerator::TestContext::Plug(Register reg) const {
285 // For simplicity we always test the accumulator register. 286 // For simplicity we always test the accumulator register.
286 __ Move(result_register(), reg); 287 __ Move(result_register(), reg);
287 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 288 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
288 codegen()->DoTest(this); 289 codegen()->DoTest(this);
289 } 290 }
290 291
291 292
292 void FullCodeGenerator::EffectContext::Plug(bool flag) const {} 293 void FullCodeGenerator::EffectContext::Plug(bool flag) const {}
293 294
294 295
295 void FullCodeGenerator::EffectContext::PlugTOS() const { 296 void FullCodeGenerator::EffectContext::PlugTOS() const {
297 codegen()->OperandStackDepthDecrement(1);
296 __ Drop(1); 298 __ Drop(1);
297 } 299 }
298 300
299 301
300 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 302 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
303 codegen()->OperandStackDepthDecrement(1);
301 __ Pop(result_register()); 304 __ Pop(result_register());
302 } 305 }
303 306
304 307
305 void FullCodeGenerator::StackValueContext::PlugTOS() const { 308 void FullCodeGenerator::StackValueContext::PlugTOS() const {
306 } 309 }
307 310
308 311
309 void FullCodeGenerator::TestContext::PlugTOS() const { 312 void FullCodeGenerator::TestContext::PlugTOS() const {
313 codegen()->OperandStackDepthDecrement(1);
310 // For simplicity we always test the accumulator register. 314 // For simplicity we always test the accumulator register.
311 __ Pop(result_register()); 315 __ Pop(result_register());
312 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 316 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
313 codegen()->DoTest(this); 317 codegen()->DoTest(this);
314 } 318 }
315 319
316 320
317 void FullCodeGenerator::EffectContext::PrepareTest( 321 void FullCodeGenerator::EffectContext::PrepareTest(
318 Label* materialize_true, 322 Label* materialize_true,
319 Label* materialize_false, 323 Label* materialize_false,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 } 435 }
432 436
433 437
434 int FullCodeGenerator::DeclareGlobalsFlags() { 438 int FullCodeGenerator::DeclareGlobalsFlags() {
435 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); 439 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode()));
436 return DeclareGlobalsEvalFlag::encode(is_eval()) | 440 return DeclareGlobalsEvalFlag::encode(is_eval()) |
437 DeclareGlobalsNativeFlag::encode(is_native()) | 441 DeclareGlobalsNativeFlag::encode(is_native()) |
438 DeclareGlobalsLanguageMode::encode(language_mode()); 442 DeclareGlobalsLanguageMode::encode(language_mode());
439 } 443 }
440 444
445 void FullCodeGenerator::PushOperand(MemOperand operand) {
446 OperandStackDepthIncrement(1);
447 __ Push(operand);
448 }
449
450 void FullCodeGenerator::PushOperand(Handle<Object> handle) {
451 OperandStackDepthIncrement(1);
452 __ Push(handle);
453 }
454
455 void FullCodeGenerator::PushOperand(Smi* smi) {
456 OperandStackDepthIncrement(1);
457 __ Push(smi);
458 }
459
460 void FullCodeGenerator::PushOperand(Register reg) {
461 OperandStackDepthIncrement(1);
462 __ Push(reg);
463 }
464
465 void FullCodeGenerator::PopOperand(Register reg) {
466 OperandStackDepthDecrement(1);
467 __ Pop(reg);
468 }
469
470 void FullCodeGenerator::DropOperands(int count) {
471 OperandStackDepthDecrement(count);
472 __ Drop(count);
473 }
474
475 void FullCodeGenerator::CallRuntimeWithOperands(Runtime::FunctionId id) {
476 OperandStackDepthDecrement(Runtime::FunctionForId(id)->nargs);
477 __ CallRuntime(id);
478 }
479
480 void FullCodeGenerator::OperandStackDepthIncrement(int count) {
481 DCHECK_GE(operand_stack_depth_, 0);
482 operand_stack_depth_ += count;
483 }
484
485 void FullCodeGenerator::OperandStackDepthDecrement(int count) {
486 DCHECK_GE(operand_stack_depth_, count);
487 operand_stack_depth_ -= count;
488 }
441 489
442 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { 490 void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
443 // Load the arguments on the stack and call the stub. 491 // Load the arguments on the stack and call the stub.
444 SubStringStub stub(isolate()); 492 SubStringStub stub(isolate());
445 ZoneList<Expression*>* args = expr->arguments(); 493 ZoneList<Expression*>* args = expr->arguments();
446 DCHECK(args->length() == 3); 494 DCHECK(args->length() == 3);
447 VisitForStackValue(args->at(0)); 495 VisitForStackValue(args->at(0));
448 VisitForStackValue(args->at(1)); 496 VisitForStackValue(args->at(1));
449 VisitForStackValue(args->at(2)); 497 VisitForStackValue(args->at(2));
450 __ CallStub(&stub); 498 __ CallStub(&stub);
499 OperandStackDepthDecrement(3);
451 context()->Plug(result_register()); 500 context()->Plug(result_register());
452 } 501 }
453 502
454 503
455 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { 504 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
456 // Load the arguments on the stack and call the stub. 505 // Load the arguments on the stack and call the stub.
457 RegExpExecStub stub(isolate()); 506 RegExpExecStub stub(isolate());
458 ZoneList<Expression*>* args = expr->arguments(); 507 ZoneList<Expression*>* args = expr->arguments();
459 DCHECK(args->length() == 4); 508 DCHECK(args->length() == 4);
460 VisitForStackValue(args->at(0)); 509 VisitForStackValue(args->at(0));
461 VisitForStackValue(args->at(1)); 510 VisitForStackValue(args->at(1));
462 VisitForStackValue(args->at(2)); 511 VisitForStackValue(args->at(2));
463 VisitForStackValue(args->at(3)); 512 VisitForStackValue(args->at(3));
464 __ CallStub(&stub); 513 __ CallStub(&stub);
514 OperandStackDepthDecrement(4);
465 context()->Plug(result_register()); 515 context()->Plug(result_register());
466 } 516 }
467 517
468 518
469 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { 519 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
470 // Load the arguments on the stack and call the runtime function. 520 // Load the arguments on the stack and call the runtime function.
521 MathPowStub stub(isolate(), MathPowStub::ON_STACK);
471 ZoneList<Expression*>* args = expr->arguments(); 522 ZoneList<Expression*>* args = expr->arguments();
472 DCHECK(args->length() == 2); 523 DCHECK(args->length() == 2);
473 VisitForStackValue(args->at(0)); 524 VisitForStackValue(args->at(0));
474 VisitForStackValue(args->at(1)); 525 VisitForStackValue(args->at(1));
475
476 MathPowStub stub(isolate(), MathPowStub::ON_STACK);
477 __ CallStub(&stub); 526 __ CallStub(&stub);
527 OperandStackDepthDecrement(2);
478 context()->Plug(result_register()); 528 context()->Plug(result_register());
479 } 529 }
480 530
481 531
482 void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr, 532 void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr,
483 const Callable& callable) { 533 const Callable& callable) {
484 ZoneList<Expression*>* args = expr->arguments(); 534 ZoneList<Expression*>* args = expr->arguments();
485 int param_count = callable.descriptor().GetRegisterParameterCount(); 535 int param_count = callable.descriptor().GetRegisterParameterCount();
486 DCHECK_EQ(args->length(), param_count); 536 DCHECK_EQ(args->length(), param_count);
487 537
488 if (param_count > 0) { 538 if (param_count > 0) {
489 int last = param_count - 1; 539 int last = param_count - 1;
490 // Put all but last arguments on stack. 540 // Put all but last arguments on stack.
491 for (int i = 0; i < last; i++) { 541 for (int i = 0; i < last; i++) {
492 VisitForStackValue(args->at(i)); 542 VisitForStackValue(args->at(i));
493 } 543 }
494 // The last argument goes to the accumulator. 544 // The last argument goes to the accumulator.
495 VisitForAccumulatorValue(args->at(last)); 545 VisitForAccumulatorValue(args->at(last));
496 546
497 // Move the arguments to the registers, as required by the stub. 547 // Move the arguments to the registers, as required by the stub.
498 __ Move(callable.descriptor().GetRegisterParameter(last), 548 __ Move(callable.descriptor().GetRegisterParameter(last),
499 result_register()); 549 result_register());
500 for (int i = last; i-- > 0;) { 550 for (int i = last; i-- > 0;) {
501 __ Pop(callable.descriptor().GetRegisterParameter(i)); 551 PopOperand(callable.descriptor().GetRegisterParameter(i));
502 } 552 }
503 } 553 }
504 __ Call(callable.code(), RelocInfo::CODE_TARGET); 554 __ Call(callable.code(), RelocInfo::CODE_TARGET);
505 context()->Plug(result_register()); 555 context()->Plug(result_register());
506 } 556 }
507 557
508 558
509 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { 559 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
510 EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate())); 560 EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate()));
511 } 561 }
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 current = current->Exit(&stack_depth, &context_length); 995 current = current->Exit(&stack_depth, &context_length);
946 } 996 }
947 __ Drop(stack_depth); 997 __ Drop(stack_depth);
948 EmitReturnSequence(); 998 EmitReturnSequence();
949 } 999 }
950 1000
951 1001
952 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, 1002 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
953 BailoutId bailout_id) { 1003 BailoutId bailout_id) {
954 VisitForStackValue(property->key()); 1004 VisitForStackValue(property->key());
955 __ CallRuntime(Runtime::kToName); 1005 CallRuntimeWithOperands(Runtime::kToName);
956 PrepareForBailoutForId(bailout_id, NO_REGISTERS); 1006 PrepareForBailoutForId(bailout_id, NO_REGISTERS);
957 __ Push(result_register()); 1007 PushOperand(result_register());
958 } 1008 }
959 1009
960 1010
961 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1011 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
962 Comment cmnt(masm_, "[ ReturnStatement"); 1012 Comment cmnt(masm_, "[ ReturnStatement");
963 SetStatementPosition(stmt); 1013 SetStatementPosition(stmt);
964 Expression* expr = stmt->expression(); 1014 Expression* expr = stmt->expression();
965 VisitForAccumulatorValue(expr); 1015 VisitForAccumulatorValue(expr);
966 EmitUnwindAndReturn(); 1016 EmitUnwindAndReturn();
967 } 1017 }
968 1018
969 1019
970 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 1020 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
971 Comment cmnt(masm_, "[ WithStatement"); 1021 Comment cmnt(masm_, "[ WithStatement");
972 SetStatementPosition(stmt); 1022 SetStatementPosition(stmt);
973 1023
974 VisitForAccumulatorValue(stmt->expression()); 1024 VisitForAccumulatorValue(stmt->expression());
975 Callable callable = CodeFactory::ToObject(isolate()); 1025 Callable callable = CodeFactory::ToObject(isolate());
976 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); 1026 __ Move(callable.descriptor().GetRegisterParameter(0), result_register());
977 __ Call(callable.code(), RelocInfo::CODE_TARGET); 1027 __ Call(callable.code(), RelocInfo::CODE_TARGET);
978 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); 1028 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS);
979 __ Push(result_register()); 1029 PushOperand(result_register());
980 PushFunctionArgumentForContextAllocation(); 1030 PushFunctionArgumentForContextAllocation();
981 __ CallRuntime(Runtime::kPushWithContext); 1031 CallRuntimeWithOperands(Runtime::kPushWithContext);
982 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1032 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
983 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 1033 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
984 1034
985 Scope* saved_scope = scope(); 1035 Scope* saved_scope = scope();
986 scope_ = stmt->scope(); 1036 scope_ = stmt->scope();
987 { WithOrCatch body(this); 1037 { WithOrCatch body(this);
988 Visit(stmt->statement()); 1038 Visit(stmt->statement());
989 } 1039 }
990 scope_ = saved_scope; 1040 scope_ = saved_scope;
991 1041
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 // result register. 1214 // result register.
1165 1215
1166 Label try_entry, handler_entry, exit; 1216 Label try_entry, handler_entry, exit;
1167 __ jmp(&try_entry); 1217 __ jmp(&try_entry);
1168 __ bind(&handler_entry); 1218 __ bind(&handler_entry);
1169 ClearPendingMessage(); 1219 ClearPendingMessage();
1170 1220
1171 // Exception handler code, the exception is in the result register. 1221 // Exception handler code, the exception is in the result register.
1172 // Extend the context before executing the catch block. 1222 // Extend the context before executing the catch block.
1173 { Comment cmnt(masm_, "[ Extend catch context"); 1223 { Comment cmnt(masm_, "[ Extend catch context");
1174 __ Push(stmt->variable()->name()); 1224 PushOperand(stmt->variable()->name());
1175 __ Push(result_register()); 1225 PushOperand(result_register());
1176 PushFunctionArgumentForContextAllocation(); 1226 PushFunctionArgumentForContextAllocation();
1177 __ CallRuntime(Runtime::kPushCatchContext); 1227 CallRuntimeWithOperands(Runtime::kPushCatchContext);
1178 StoreToFrameField(StandardFrameConstants::kContextOffset, 1228 StoreToFrameField(StandardFrameConstants::kContextOffset,
1179 context_register()); 1229 context_register());
1180 } 1230 }
1181 1231
1182 Scope* saved_scope = scope(); 1232 Scope* saved_scope = scope();
1183 scope_ = stmt->scope(); 1233 scope_ = stmt->scope();
1184 DCHECK(scope_->declarations()->is_empty()); 1234 DCHECK(scope_->declarations()->is_empty());
1185 { WithOrCatch catch_body(this); 1235 { WithOrCatch catch_body(this);
1186 Visit(stmt->catch_block()); 1236 Visit(stmt->catch_block());
1187 } 1237 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 // value in the result register with one that's safe for GC because the 1305 // value in the result register with one that's safe for GC because the
1256 // finally block will unconditionally preserve the result register on the 1306 // finally block will unconditionally preserve the result register on the
1257 // stack. 1307 // stack.
1258 ClearAccumulator(); 1308 ClearAccumulator();
1259 deferred.EmitFallThrough(); 1309 deferred.EmitFallThrough();
1260 // Fall through to the finally block. 1310 // Fall through to the finally block.
1261 1311
1262 // Finally block implementation. 1312 // Finally block implementation.
1263 __ bind(&finally_entry); 1313 __ bind(&finally_entry);
1264 Comment cmnt_finally(masm(), "[ Finally block"); 1314 Comment cmnt_finally(masm(), "[ Finally block");
1315 OperandStackDepthIncrement(2); // Token and accumulator are on stack.
1265 EnterFinallyBlock(); 1316 EnterFinallyBlock();
1266 { 1317 {
1267 Finally finally_body(this); 1318 Finally finally_body(this);
1268 Visit(stmt->finally_block()); 1319 Visit(stmt->finally_block());
1269 } 1320 }
1270 ExitFinallyBlock(); // Return to the calling code. 1321 ExitFinallyBlock();
1322 OperandStackDepthDecrement(2); // Token and accumulator are on stack.
Jarin 2016/02/19 06:52:04 Nit: are -> were
Michael Starzinger 2016/02/19 09:24:04 Done.
1271 1323
1272 { 1324 {
1273 Comment cmnt_deferred(masm(), "[ Post-finally dispatch"); 1325 Comment cmnt_deferred(masm(), "[ Post-finally dispatch");
1274 deferred.EmitCommands(); 1326 deferred.EmitCommands(); // Return to the calling code.
1275 } 1327 }
1276 } 1328 }
1277 1329
1278 1330
1279 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1331 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1280 Comment cmnt(masm_, "[ DebuggerStatement"); 1332 Comment cmnt(masm_, "[ DebuggerStatement");
1281 SetStatementPosition(stmt); 1333 SetStatementPosition(stmt);
1282 1334
1283 __ DebugBreak(); 1335 __ DebugBreak();
1284 // Ignore the return value. 1336 // Ignore the return value.
1285 1337
1286 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); 1338 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS);
1287 } 1339 }
1288 1340
1289 1341
1290 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { 1342 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) {
1291 UNREACHABLE(); 1343 UNREACHABLE();
1292 } 1344 }
1293 1345
1294 1346
1295 void FullCodeGenerator::VisitConditional(Conditional* expr) { 1347 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1296 Comment cmnt(masm_, "[ Conditional"); 1348 Comment cmnt(masm_, "[ Conditional");
1297 Label true_case, false_case, done; 1349 Label true_case, false_case, done;
1298 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1350 VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1299 1351
1352 int original_stack_depth = operand_stack_depth_;
1300 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1353 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
1301 __ bind(&true_case); 1354 __ bind(&true_case);
1302 SetExpressionPosition(expr->then_expression()); 1355 SetExpressionPosition(expr->then_expression());
1303 if (context()->IsTest()) { 1356 if (context()->IsTest()) {
1304 const TestContext* for_test = TestContext::cast(context()); 1357 const TestContext* for_test = TestContext::cast(context());
1305 VisitForControl(expr->then_expression(), 1358 VisitForControl(expr->then_expression(),
1306 for_test->true_label(), 1359 for_test->true_label(),
1307 for_test->false_label(), 1360 for_test->false_label(),
1308 NULL); 1361 NULL);
1309 } else { 1362 } else {
1310 VisitInDuplicateContext(expr->then_expression()); 1363 VisitInDuplicateContext(expr->then_expression());
1311 __ jmp(&done); 1364 __ jmp(&done);
1312 } 1365 }
1313 1366
1367 operand_stack_depth_ = original_stack_depth;
1314 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1368 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1315 __ bind(&false_case); 1369 __ bind(&false_case);
1316 SetExpressionPosition(expr->else_expression()); 1370 SetExpressionPosition(expr->else_expression());
1317 VisitInDuplicateContext(expr->else_expression()); 1371 VisitInDuplicateContext(expr->else_expression());
1318 // If control flow falls through Visit, merge it with true case here. 1372 // If control flow falls through Visit, merge it with true case here.
1319 if (!context()->IsTest()) { 1373 if (!context()->IsTest()) {
1320 __ bind(&done); 1374 __ bind(&done);
1321 } 1375 }
1322 } 1376 }
1323 1377
(...skipping 21 matching lines...) Expand all
1345 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { 1399 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
1346 Comment cmnt(masm_, "[ ClassLiteral"); 1400 Comment cmnt(masm_, "[ ClassLiteral");
1347 1401
1348 { 1402 {
1349 EnterBlockScopeIfNeeded block_scope_state( 1403 EnterBlockScopeIfNeeded block_scope_state(
1350 this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId()); 1404 this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId());
1351 1405
1352 if (lit->extends() != NULL) { 1406 if (lit->extends() != NULL) {
1353 VisitForStackValue(lit->extends()); 1407 VisitForStackValue(lit->extends());
1354 } else { 1408 } else {
1355 __ Push(isolate()->factory()->the_hole_value()); 1409 PushOperand(isolate()->factory()->the_hole_value());
1356 } 1410 }
1357 1411
1358 VisitForStackValue(lit->constructor()); 1412 VisitForStackValue(lit->constructor());
1359 1413
1360 __ Push(Smi::FromInt(lit->start_position())); 1414 PushOperand(Smi::FromInt(lit->start_position()));
1361 __ Push(Smi::FromInt(lit->end_position())); 1415 PushOperand(Smi::FromInt(lit->end_position()));
1362 1416
1363 __ CallRuntime(Runtime::kDefineClass); 1417 CallRuntimeWithOperands(Runtime::kDefineClass);
1364 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); 1418 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG);
1365 __ Push(result_register()); 1419 PushOperand(result_register());
1366 1420
1367 // Load the "prototype" from the constructor. 1421 // Load the "prototype" from the constructor.
1368 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); 1422 __ Move(LoadDescriptor::ReceiverRegister(), result_register());
1369 __ LoadRoot(LoadDescriptor::NameRegister(), 1423 __ LoadRoot(LoadDescriptor::NameRegister(),
1370 Heap::kprototype_stringRootIndex); 1424 Heap::kprototype_stringRootIndex);
1371 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); 1425 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot()));
1372 CallLoadIC(NOT_INSIDE_TYPEOF); 1426 CallLoadIC(NOT_INSIDE_TYPEOF);
1373 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); 1427 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG);
1374 __ Push(result_register()); 1428 PushOperand(result_register());
1375 1429
1376 EmitClassDefineProperties(lit); 1430 EmitClassDefineProperties(lit);
1377 1431
1378 // Set both the prototype and constructor to have fast properties, and also 1432 // Set both the prototype and constructor to have fast properties, and also
1379 // freeze them in strong mode. 1433 // freeze them in strong mode.
1380 __ CallRuntime(Runtime::kFinalizeClassDefinition); 1434 CallRuntimeWithOperands(Runtime::kFinalizeClassDefinition);
1381 1435
1382 if (lit->class_variable_proxy() != nullptr) { 1436 if (lit->class_variable_proxy() != nullptr) {
1383 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, 1437 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT,
1384 lit->ProxySlot()); 1438 lit->ProxySlot());
1385 } 1439 }
1386 } 1440 }
1387 1441
1388 context()->Plug(result_register()); 1442 context()->Plug(result_register());
1389 } 1443 }
1390 1444
1391 1445
1392 void FullCodeGenerator::VisitNativeFunctionLiteral( 1446 void FullCodeGenerator::VisitNativeFunctionLiteral(
1393 NativeFunctionLiteral* expr) { 1447 NativeFunctionLiteral* expr) {
1394 Comment cmnt(masm_, "[ NativeFunctionLiteral"); 1448 Comment cmnt(masm_, "[ NativeFunctionLiteral");
1395 Handle<SharedFunctionInfo> shared = 1449 Handle<SharedFunctionInfo> shared =
1396 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); 1450 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name());
1397 EmitNewClosure(shared, false); 1451 EmitNewClosure(shared, false);
1398 } 1452 }
1399 1453
1400 1454
1401 void FullCodeGenerator::VisitThrow(Throw* expr) { 1455 void FullCodeGenerator::VisitThrow(Throw* expr) {
1402 Comment cmnt(masm_, "[ Throw"); 1456 Comment cmnt(masm_, "[ Throw");
1403 VisitForStackValue(expr->exception()); 1457 VisitForStackValue(expr->exception());
1404 SetExpressionPosition(expr); 1458 SetExpressionPosition(expr);
1405 __ CallRuntime(Runtime::kThrow); 1459 CallRuntimeWithOperands(Runtime::kThrow);
1406 // Never returns here. 1460 // Never returns here.
1461
1462 // Even though this expression doesn't produce a value, we need to simulate
1463 // plugging of the value context to ensure stack depth tracking is in sync.
1464 if (context()->IsStackValue()) OperandStackDepthIncrement(1);
1407 } 1465 }
1408 1466
1409 1467
1410 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) { 1468 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) {
1411 HandlerTableEntry* entry = &handler_table_[handler_index]; 1469 HandlerTableEntry* entry = &handler_table_[handler_index];
1412 entry->range_start = masm()->pc_offset(); 1470 entry->range_start = masm()->pc_offset();
1413 entry->handler_offset = handler->pos(); 1471 entry->handler_offset = handler->pos();
1414 entry->try_catch_depth = try_catch_depth_; 1472 entry->try_catch_depth = try_catch_depth_;
1473 entry->stack_depth = operand_stack_depth_;
1415 1474
1416 // Determine expression stack depth of try statement. 1475 // We are using the operand stack depth, check for accuracy.
1417 int stack_depth = info_->scope()->num_stack_slots(); // Include stack locals. 1476 EmitOperandStackDepthCheck();
1418 for (NestedStatement* current = nesting_stack_; current != NULL; /*nop*/) {
1419 current = current->AccumulateDepth(&stack_depth);
1420 }
1421 entry->stack_depth = stack_depth;
1422 1477
1423 // Push context onto operand stack. 1478 // Push context onto operand stack.
1424 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); 1479 STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1425 __ Push(context_register()); 1480 PushOperand(context_register());
1426 } 1481 }
1427 1482
1428 1483
1429 void FullCodeGenerator::ExitTryBlock(int handler_index) { 1484 void FullCodeGenerator::ExitTryBlock(int handler_index) {
1430 HandlerTableEntry* entry = &handler_table_[handler_index]; 1485 HandlerTableEntry* entry = &handler_table_[handler_index];
1431 entry->range_end = masm()->pc_offset(); 1486 entry->range_end = masm()->pc_offset();
1432 1487
1433 // Drop context from operand stack. 1488 // Drop context from operand stack.
1434 __ Drop(TryBlockConstant::kElementCount); 1489 DropOperands(TryBlockConstant::kElementCount);
1435 } 1490 }
1436 1491
1437 1492
1438 void FullCodeGenerator::VisitCall(Call* expr) { 1493 void FullCodeGenerator::VisitCall(Call* expr) {
1439 #ifdef DEBUG 1494 #ifdef DEBUG
1440 // We want to verify that RecordJSReturnSite gets called on all paths 1495 // We want to verify that RecordJSReturnSite gets called on all paths
1441 // through this function. Avoid early returns. 1496 // through this function. Avoid early returns.
1442 expr->return_is_recorded_ = false; 1497 expr->return_is_recorded_ = false;
1443 #endif 1498 #endif
1444 1499
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 break; 1532 break;
1478 case Call::KEYED_SUPER_PROPERTY_CALL: 1533 case Call::KEYED_SUPER_PROPERTY_CALL:
1479 EmitKeyedSuperCallWithLoadIC(expr); 1534 EmitKeyedSuperCallWithLoadIC(expr);
1480 break; 1535 break;
1481 case Call::SUPER_CALL: 1536 case Call::SUPER_CALL:
1482 EmitSuperConstructorCall(expr); 1537 EmitSuperConstructorCall(expr);
1483 break; 1538 break;
1484 case Call::OTHER_CALL: 1539 case Call::OTHER_CALL:
1485 // Call to an arbitrary expression not handled specially above. 1540 // Call to an arbitrary expression not handled specially above.
1486 VisitForStackValue(callee); 1541 VisitForStackValue(callee);
1542 OperandStackDepthIncrement(1);
1487 __ PushRoot(Heap::kUndefinedValueRootIndex); 1543 __ PushRoot(Heap::kUndefinedValueRootIndex);
1488 // Emit function call. 1544 // Emit function call.
1489 EmitCall(expr); 1545 EmitCall(expr);
1490 break; 1546 break;
1491 } 1547 }
1492 1548
1493 #ifdef DEBUG 1549 #ifdef DEBUG
1494 // RecordJSReturnSite should have been called. 1550 // RecordJSReturnSite should have been called.
1495 DCHECK(expr->return_is_recorded_); 1551 DCHECK(expr->return_is_recorded_);
1496 #endif 1552 #endif
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 1749
1694 if (scope == NULL) { 1750 if (scope == NULL) {
1695 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); 1751 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
1696 needs_block_context_ = false; 1752 needs_block_context_ = false;
1697 } else { 1753 } else {
1698 needs_block_context_ = scope->NeedsContext(); 1754 needs_block_context_ = scope->NeedsContext();
1699 codegen_->scope_ = scope; 1755 codegen_->scope_ = scope;
1700 { 1756 {
1701 if (needs_block_context_) { 1757 if (needs_block_context_) {
1702 Comment cmnt(masm(), "[ Extend block context"); 1758 Comment cmnt(masm(), "[ Extend block context");
1703 __ Push(scope->GetScopeInfo(codegen->isolate())); 1759 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate()));
1704 codegen_->PushFunctionArgumentForContextAllocation(); 1760 codegen_->PushFunctionArgumentForContextAllocation();
1705 __ CallRuntime(Runtime::kPushBlockContext); 1761 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext);
1706 1762
1707 // Replace the context stored in the frame. 1763 // Replace the context stored in the frame.
1708 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, 1764 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1709 codegen_->context_register()); 1765 codegen_->context_register());
1710 } 1766 }
1711 CHECK_EQ(0, scope->num_stack_slots()); 1767 CHECK_EQ(0, scope->num_stack_slots());
1712 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); 1768 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
1713 } 1769 }
1714 { 1770 {
1715 Comment cmnt(masm(), "[ Declarations"); 1771 Comment cmnt(masm(), "[ Declarations");
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() || 1846 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() ||
1791 var->initializer_position() >= proxy->position(); 1847 var->initializer_position() >= proxy->position();
1792 } 1848 }
1793 1849
1794 1850
1795 #undef __ 1851 #undef __
1796 1852
1797 1853
1798 } // namespace internal 1854 } // namespace internal
1799 } // namespace v8 1855 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698