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

Side by Side Diff: src/ia32/fast-codegen-ia32.cc

Issue 339004: Eliminate the constant location used for literals in the AST.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 Comment cmnt(masm_, "[ ExpressionStatement"); 129 Comment cmnt(masm_, "[ ExpressionStatement");
130 SetStatementPosition(stmt); 130 SetStatementPosition(stmt);
131 Visit(stmt->expression()); 131 Visit(stmt->expression());
132 } 132 }
133 133
134 134
135 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 135 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
136 Comment cmnt(masm_, "[ ReturnStatement"); 136 Comment cmnt(masm_, "[ ReturnStatement");
137 SetStatementPosition(stmt); 137 SetStatementPosition(stmt);
138 Expression* expr = stmt->expression(); 138 Expression* expr = stmt->expression();
139 Visit(expr); 139 // Complete the statement based on the type of the subexpression.
140 if (expr->AsLiteral() != NULL) {
141 __ mov(eax, expr->AsLiteral()->handle());
142 } else {
143 Visit(expr);
144 ASSERT(expr->location().is_temporary());
145 __ pop(eax);
146 }
140 147
141 // Complete the statement based on the location of the subexpression.
142 Location source = expr->location();
143 ASSERT(!source.is_nowhere());
144 if (source.is_temporary()) {
145 __ pop(eax);
146 } else {
147 ASSERT(source.is_constant());
148 ASSERT(expr->AsLiteral() != NULL);
149 __ mov(eax, expr->AsLiteral()->handle());
150 }
151 if (FLAG_trace) { 148 if (FLAG_trace) {
152 __ push(eax); 149 __ push(eax);
153 __ CallRuntime(Runtime::kTraceExit, 1); 150 __ CallRuntime(Runtime::kTraceExit, 1);
154 } 151 }
155 __ RecordJSReturn(); 152 __ RecordJSReturn();
156 153
157 // Do not use the leave instruction here because it is too short to 154 // Do not use the leave instruction here because it is too short to
158 // patch with the code required by the debugger. 155 // patch with the code required by the debugger.
159 __ mov(esp, ebp); 156 __ mov(esp, ebp);
160 __ pop(ebp); 157 __ pop(ebp);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 ASSERT(slot != NULL); 211 ASSERT(slot != NULL);
215 if (expr->location().is_temporary()) { 212 if (expr->location().is_temporary()) {
216 __ push(Operand(ebp, SlotOffset(slot))); 213 __ push(Operand(ebp, SlotOffset(slot)));
217 } else { 214 } else {
218 ASSERT(expr->location().is_nowhere()); 215 ASSERT(expr->location().is_nowhere());
219 } 216 }
220 } 217 }
221 } 218 }
222 219
223 220
221 void FastCodeGenerator::VisitLiteral(Literal* expr) {
222 if (expr->location().is_temporary()) {
223 __ push(Immediate(expr->handle()));
224 } else {
225 ASSERT(expr->location().is_nowhere());
226 }
227 }
228
229
224 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 230 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
225 Comment cmnt(masm_, "[ ObjectLiteral"); 231 Comment cmnt(masm_, "[ ObjectLiteral");
226 Label exists; 232 Label exists;
227 // Registers will be used as follows: 233 // Registers will be used as follows:
228 // edi = JS function. 234 // edi = JS function.
229 // ebx = literals array. 235 // ebx = literals array.
230 // eax = boilerplate 236 // eax = boilerplate
231 237
232 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 238 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
233 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 239 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 __ mov(ecx, Immediate(key->handle())); 288 __ mov(ecx, Immediate(key->handle()));
283 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 289 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
284 __ call(ic, RelocInfo::CODE_TARGET); 290 __ call(ic, RelocInfo::CODE_TARGET);
285 // StoreIC leaves the receiver on the stack. 291 // StoreIC leaves the receiver on the stack.
286 break; 292 break;
287 } 293 }
288 // fall through 294 // fall through
289 case ObjectLiteral::Property::PROTOTYPE: 295 case ObjectLiteral::Property::PROTOTYPE:
290 __ push(eax); 296 __ push(eax);
291 Visit(key); 297 Visit(key);
292 if (key->location().is_constant()) { 298 ASSERT(key->location().is_temporary());
293 __ push(Immediate(key->handle()));
294 }
295 Visit(value); 299 Visit(value);
296 ASSERT(value->location().is_temporary()); 300 ASSERT(value->location().is_temporary());
297 __ CallRuntime(Runtime::kSetProperty, 3); 301 __ CallRuntime(Runtime::kSetProperty, 3);
298 __ mov(eax, Operand(esp, 0)); // Restore result into eax. 302 __ mov(eax, Operand(esp, 0)); // Restore result into eax.
299 break; 303 break;
300 case ObjectLiteral::Property::SETTER: // fall through 304 case ObjectLiteral::Property::SETTER: // fall through
301 case ObjectLiteral::Property::GETTER: 305 case ObjectLiteral::Property::GETTER:
302 __ push(eax); 306 __ push(eax);
303 Visit(key); 307 Visit(key);
304 if (key->location().is_constant()) { 308 ASSERT(key->location().is_temporary());
305 __ push(Immediate(key->handle()));
306 }
307 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? 309 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
308 Smi::FromInt(1) : 310 Smi::FromInt(1) :
309 Smi::FromInt(0))); 311 Smi::FromInt(0)));
310 Visit(value); 312 Visit(value);
311 ASSERT(value->location().is_temporary()); 313 ASSERT(value->location().is_temporary());
312 __ CallRuntime(Runtime::kDefineAccessor, 4); 314 __ CallRuntime(Runtime::kDefineAccessor, 4);
313 __ mov(eax, Operand(esp, 0)); // Restore result into eax. 315 __ mov(eax, Operand(esp, 0)); // Restore result into eax.
314 break; 316 break;
315 default: UNREACHABLE(); 317 default: UNREACHABLE();
316 } 318 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 __ add(Operand(esp), Immediate(kPointerSize)); 422 __ add(Operand(esp), Immediate(kPointerSize));
421 } else if (destination.is_temporary() && !result_saved) { 423 } else if (destination.is_temporary() && !result_saved) {
422 __ push(eax); 424 __ push(eax);
423 } 425 }
424 } 426 }
425 427
426 428
427 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 429 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
428 Comment cmnt(masm_, "[ Assignment"); 430 Comment cmnt(masm_, "[ Assignment");
429 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 431 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
430 Expression* rhs = expr->value();
431 Visit(rhs);
432 432
433 // Left-hand side can only be a global or a (parameter or local) slot. 433 // Left-hand side can only be a global or a (parameter or local) slot.
434 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 434 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
435 ASSERT(var != NULL); 435 ASSERT(var != NULL);
436 ASSERT(var->is_global() || var->slot() != NULL); 436 ASSERT(var->is_global() || var->slot() != NULL);
437 437
438 // Complete the assignment based on the location of the right-hand-side 438 Expression* rhs = expr->value();
439 // value and the desired location of the assignment value.
440 Location destination = expr->location(); 439 Location destination = expr->location();
441 Location source = rhs->location();
442 ASSERT(!destination.is_constant());
443 ASSERT(!source.is_nowhere());
444
445 if (var->is_global()) { 440 if (var->is_global()) {
446 // Assignment to a global variable, use inline caching. Right-hand-side 441 // Assignment to a global variable, use inline caching. Right-hand-side
447 // value is passed in eax, variable name in ecx, and the global object 442 // value is passed in eax, variable name in ecx, and the global object
448 // on the stack. 443 // on the stack.
449 if (source.is_temporary()) { 444
445 // Code for the right-hand-side expression depends on its type.
446 if (rhs->AsLiteral() != NULL) {
447 __ mov(eax, rhs->AsLiteral()->handle());
448 } else {
449 ASSERT(rhs->location().is_temporary());
450 Visit(rhs);
450 __ pop(eax); 451 __ pop(eax);
451 } else {
452 ASSERT(source.is_constant());
453 ASSERT(rhs->AsLiteral() != NULL);
454 __ mov(eax, rhs->AsLiteral()->handle());
455 } 452 }
456 __ mov(ecx, var->name()); 453 __ mov(ecx, var->name());
457 __ push(CodeGenerator::GlobalObject()); 454 __ push(CodeGenerator::GlobalObject());
458 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 455 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
459 __ call(ic, RelocInfo::CODE_TARGET); 456 __ call(ic, RelocInfo::CODE_TARGET);
460 // Overwrite the global object on the stack with the result if needed. 457 // Overwrite the global object on the stack with the result if needed.
461 if (destination.is_temporary()) { 458 if (destination.is_temporary()) {
462 __ mov(Operand(esp, 0), eax); 459 __ mov(Operand(esp, 0), eax);
463 } else { 460 } else {
464 ASSERT(destination.is_nowhere()); 461 ASSERT(destination.is_nowhere());
465 __ add(Operand(esp), Immediate(kPointerSize)); 462 __ add(Operand(esp), Immediate(kPointerSize));
466 } 463 }
467
468 } else { 464 } else {
469 // Local or parameter assignment. 465 // Local or parameter assignment.
470 if (source.is_temporary()) { 466
467 // Code for the right-hand side expression depends on its type.
468 if (rhs->AsLiteral() != NULL) {
469 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
470 // discarded result. Always perform the assignment.
471 __ mov(eax, rhs->AsLiteral()->handle());
472 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
473 if (destination.is_temporary()) {
474 // Case 'temp <- (var = constant)'. Save result.
475 __ push(eax);
fschneider 2009/10/26 17:57:20 Add an assert here to be consistent with the rest
476 }
477 } else {
478 ASSERT(rhs->location().is_temporary());
479 Visit(rhs);
471 if (destination.is_temporary()) { 480 if (destination.is_temporary()) {
472 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 481 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
473 // temporary on the stack. 482 // temporary on the stack.
474 __ mov(eax, Operand(esp, 0)); 483 __ mov(eax, Operand(esp, 0));
475 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 484 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
476 } else { 485 } else {
477 ASSERT(destination.is_nowhere()); 486 ASSERT(destination.is_nowhere());
478 // Case 'var = temp'. Discard right-hand-side temporary. 487 // Case 'var = temp'. Discard right-hand-side temporary.
479 __ pop(Operand(ebp, SlotOffset(var->slot()))); 488 __ pop(Operand(ebp, SlotOffset(var->slot())));
480 } 489 }
481 } else {
482 ASSERT(source.is_constant());
483 ASSERT(rhs->AsLiteral() != NULL);
484 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
485 // discarded result. Always perform the assignment.
486 __ mov(eax, rhs->AsLiteral()->handle());
487 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
488 if (destination.is_temporary()) {
489 // Case 'temp <- (var = constant)'. Save result.
490 __ push(eax);
491 }
492 } 490 }
493 } 491 }
494 } 492 }
495 493
496 494
497 void FastCodeGenerator::VisitCall(Call* expr) { 495 void FastCodeGenerator::VisitCall(Call* expr) {
498 Expression* fun = expr->expression(); 496 Expression* fun = expr->expression();
499 ZoneList<Expression*>* args = expr->arguments(); 497 ZoneList<Expression*>* args = expr->arguments();
500 Variable* var = fun->AsVariableProxy()->AsVariable(); 498 Variable* var = fun->AsVariableProxy()->AsVariable();
501 ASSERT(var != NULL && !var->is_this() && var->is_global()); 499 ASSERT(var != NULL && !var->is_this() && var->is_global());
502 ASSERT(!var->is_possibly_eval()); 500 ASSERT(!var->is_possibly_eval());
503 501
504 __ push(Immediate(var->name())); 502 __ push(Immediate(var->name()));
505 // Push global object (receiver). 503 // Push global object (receiver).
506 __ push(CodeGenerator::GlobalObject()); 504 __ push(CodeGenerator::GlobalObject());
507 int arg_count = args->length(); 505 int arg_count = args->length();
508 for (int i = 0; i < arg_count; i++) { 506 for (int i = 0; i < arg_count; i++) {
509 Visit(args->at(i)); 507 Visit(args->at(i));
510 ASSERT(!args->at(i)->location().is_nowhere()); 508 ASSERT(args->at(i)->location().is_temporary());
511 if (args->at(i)->location().is_constant()) {
512 ASSERT(args->at(i)->AsLiteral() != NULL);
513 __ push(Immediate(args->at(i)->AsLiteral()->handle()));
514 }
515 } 509 }
516 // Record source position for debugger 510 // Record source position for debugger
517 SetSourcePosition(expr->position()); 511 SetSourcePosition(expr->position());
518 // Call the IC initialization code. 512 // Call the IC initialization code.
519 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 513 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
520 NOT_IN_LOOP); 514 NOT_IN_LOOP);
521 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 515 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
522 // Restore context register. 516 // Restore context register.
523 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 517 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
524 // Discard the function left on TOS. 518 // Discard the function left on TOS.
(...skipping 10 matching lines...) Expand all
535 Comment cmnt(masm_, "[ CallRuntime"); 529 Comment cmnt(masm_, "[ CallRuntime");
536 ZoneList<Expression*>* args = expr->arguments(); 530 ZoneList<Expression*>* args = expr->arguments();
537 Runtime::Function* function = expr->function(); 531 Runtime::Function* function = expr->function();
538 532
539 ASSERT(function != NULL); 533 ASSERT(function != NULL);
540 534
541 // Push the arguments ("left-to-right"). 535 // Push the arguments ("left-to-right").
542 int arg_count = args->length(); 536 int arg_count = args->length();
543 for (int i = 0; i < arg_count; i++) { 537 for (int i = 0; i < arg_count; i++) {
544 Visit(args->at(i)); 538 Visit(args->at(i));
545 ASSERT(!args->at(i)->location().is_nowhere()); 539 ASSERT(args->at(i)->location().is_temporary());
546 if (args->at(i)->location().is_constant()) {
547 ASSERT(args->at(i)->AsLiteral() != NULL);
548 __ push(Immediate(args->at(i)->AsLiteral()->handle()));
549 } else {
550 ASSERT(args->at(i)->location().is_temporary());
551 // If location is temporary, it is already on the stack,
552 // so nothing to do here.
553 }
554 } 540 }
555 541
556 __ CallRuntime(function, arg_count); 542 __ CallRuntime(function, arg_count);
557 if (expr->location().is_temporary()) { 543 if (expr->location().is_temporary()) {
558 __ push(eax); 544 __ push(eax);
559 } else { 545 } else {
560 ASSERT(expr->location().is_nowhere()); 546 ASSERT(expr->location().is_nowhere());
561 } 547 }
562 } 548 }
563 549
564 550
565 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 551 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
566 // Compile a short-circuited boolean or operation in a non-test 552 // Compile a short-circuited boolean or operation in a non-test
567 // context. 553 // context.
568 ASSERT(expr->op() == Token::OR); 554 ASSERT(expr->op() == Token::OR);
569 // Compile (e0 || e1) as if it were 555 // Compile (e0 || e1) as if it were
570 // (let (temp = e0) temp ? temp : e1). 556 // (let (temp = e0) temp ? temp : e1).
571 557
572 Label eval_right, done; 558 Label eval_right, done;
573 Location destination = expr->location(); 559 Location destination = expr->location();
574 ASSERT(!destination.is_constant()); 560 Expression* left = expr->left();
561 Expression* right = expr->right();
575 562
576 Expression* left = expr->left();
577 Location left_source = left->location();
578 ASSERT(!left_source.is_nowhere());
579
580 Expression* right = expr->right();
581 Location right_source = right->location();
582 ASSERT(!right_source.is_nowhere());
583
584 Visit(left);
585 // Use the shared ToBoolean stub to find the boolean value of the 563 // Use the shared ToBoolean stub to find the boolean value of the
586 // left-hand subexpression. Load the value into eax to perform some 564 // left-hand subexpression. Load the value into eax to perform some
587 // inlined checks assumed by the stub. 565 // inlined checks assumed by the stub.
588 if (left_source.is_temporary()) { 566
567 // Compile the left-hand value into eax. Put it on the stack if we may
568 // need it as the value of the whole expression.
569 if (left->AsLiteral() != NULL) {
570 __ mov(eax, left->AsLiteral()->handle());
571 if (destination.is_temporary()) __ push(eax);
fschneider 2009/10/26 17:57:20 May want to add an assert here to be consistent wi
572 } else {
573 Visit(left);
574 ASSERT(left->location().is_temporary());
589 if (destination.is_temporary()) { 575 if (destination.is_temporary()) {
590 // Copy the left-hand value into eax because we may need it as the 576 // Copy the left-hand value into eax because we may need it as the
591 // final result. 577 // final result.
592 __ mov(eax, Operand(esp, 0)); 578 __ mov(eax, Operand(esp, 0));
593 } else { 579 } else {
594 // Pop the left-hand value into eax because we will not need it as the 580 // Pop the left-hand value into eax because we will not need it as the
595 // final result. 581 // final result.
596 __ pop(eax); 582 __ pop(eax);
fschneider 2009/10/26 17:57:20 Adding an assert to be consistent on all platforms
597 } 583 }
598 } else {
599 // Load the left-hand value into eax. Put it on the stack if we may
600 // need it.
601 ASSERT(left->AsLiteral() != NULL);
602 __ mov(eax, left->AsLiteral()->handle());
603 if (destination.is_temporary()) __ push(eax);
604 } 584 }
605 // The left-hand value is in eax. It is also on the stack iff the 585 // The left-hand value is in eax. It is also on the stack iff the
606 // destination location is temporary. 586 // destination location is temporary.
607 587
608 // Perform fast checks assumed by the stub. 588 // Perform fast checks assumed by the stub.
609 __ cmp(eax, Factory::undefined_value()); // The undefined value is false. 589 __ cmp(eax, Factory::undefined_value()); // The undefined value is false.
610 __ j(equal, &eval_right); 590 __ j(equal, &eval_right);
611 __ cmp(eax, Factory::true_value()); // True is true. 591 __ cmp(eax, Factory::true_value()); // True is true.
612 __ j(equal, &done); 592 __ j(equal, &done);
613 __ cmp(eax, Factory::false_value()); // False is false. 593 __ cmp(eax, Factory::false_value()); // False is false.
614 __ j(equal, &eval_right); 594 __ j(equal, &eval_right);
615 ASSERT(kSmiTag == 0); 595 ASSERT(kSmiTag == 0);
616 __ test(eax, Operand(eax)); // The smi zero is false. 596 __ test(eax, Operand(eax)); // The smi zero is false.
617 __ j(zero, &eval_right); 597 __ j(zero, &eval_right);
618 __ test(eax, Immediate(kSmiTagMask)); // All other smis are true. 598 __ test(eax, Immediate(kSmiTagMask)); // All other smis are true.
619 __ j(zero, &done); 599 __ j(zero, &done);
620 600
621 // Call the stub for all other cases. 601 // Call the stub for all other cases.
622 __ push(eax); 602 __ push(eax);
623 ToBooleanStub stub; 603 ToBooleanStub stub;
624 __ CallStub(&stub); 604 __ CallStub(&stub);
625 __ test(eax, Operand(eax)); // The stub returns nonzero for true. 605 __ test(eax, Operand(eax)); // The stub returns nonzero for true.
626 __ j(not_zero, &done); 606 __ j(not_zero, &done);
627 607
628 __ bind(&eval_right); 608 __ bind(&eval_right);
629 // Discard the left-hand value if present on the stack. 609 // Discard the left-hand value if present on the stack.
630 if (destination.is_temporary()) { 610 if (destination.is_temporary()) {
631 __ add(Operand(esp), Immediate(kPointerSize)); 611 __ add(Operand(esp), Immediate(kPointerSize));
632 } 612 }
633 Visit(right);
634
635 // Save or discard the right-hand value as needed. 613 // Save or discard the right-hand value as needed.
636 if (destination.is_temporary() && right_source.is_constant()) { 614 if (right->AsLiteral() != NULL) {
637 ASSERT(right->AsLiteral() != NULL); 615 if (destination.is_temporary()) {
638 __ push(Immediate(right->AsLiteral()->handle())); 616 __ push(Immediate(right->AsLiteral()->handle()));
639 } else if (destination.is_nowhere() && right_source.is_temporary()) { 617 } else {
640 __ add(Operand(esp), Immediate(kPointerSize)); 618 ASSERT(destination.is_nowhere());
619 }
620 } else {
621 Visit(right);
622 ASSERT(right->location().is_temporary());
623 if (destination.is_nowhere()) {
624 __ add(Operand(esp), Immediate(kPointerSize));
625 } else {
626 ASSERT(destination.is_temporary());
627 }
641 } 628 }
642 629
643 __ bind(&done); 630 __ bind(&done);
644 } 631 }
645 632
646 633
647 } } // namespace v8::internal 634 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698