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

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

Issue 463041: Push bleeding_edge revision 3429 to trunk to fix new reliability... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 11 years 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
« no previous file with comments | « src/version.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 __ j(not_zero, true_label); 413 __ j(not_zero, true_label);
414 __ jmp(false_label); 414 __ jmp(false_label);
415 } 415 }
416 416
417 417
418 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { 418 void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
419 Comment cmnt(masm_, "[ Declaration"); 419 Comment cmnt(masm_, "[ Declaration");
420 Variable* var = decl->proxy()->var(); 420 Variable* var = decl->proxy()->var();
421 ASSERT(var != NULL); // Must have been resolved. 421 ASSERT(var != NULL); // Must have been resolved.
422 Slot* slot = var->slot(); 422 Slot* slot = var->slot();
423 ASSERT(slot != NULL); // No global declarations here. 423 Property* prop = var->AsProperty();
424 424
425 // We have 3 cases for slots: LOOKUP, LOCAL, CONTEXT. 425 if (slot != NULL) {
426 switch (slot->type()) { 426 switch (slot->type()) {
427 case Slot::LOOKUP: { 427 case Slot::PARAMETER: // Fall through.
428 __ push(rsi); 428 case Slot::LOCAL:
429 __ Push(var->name()); 429 if (decl->mode() == Variable::CONST) {
430 // Declaration nodes are always introduced in one of two modes. 430 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
431 ASSERT(decl->mode() == Variable::VAR || decl->mode() == Variable::CONST); 431 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
432 PropertyAttributes attr = decl->mode() == Variable::VAR ? 432 } else if (decl->fun() != NULL) {
433 NONE : READ_ONLY; 433 Visit(decl->fun());
434 __ Push(Smi::FromInt(attr)); 434 __ pop(Operand(rbp, SlotOffset(var->slot())));
435 // Push initial value, if any. 435 }
436 // Note: For variables we must not push an initial value (such as 436 break;
437 // 'undefined') because we may have a (legal) redeclaration and we 437
438 // must not destroy the current value. 438 case Slot::CONTEXT:
439 if (decl->mode() == Variable::CONST) { 439 // The variable in the decl always resides in the current context.
440 __ Push(Factory::the_hole_value()); 440 ASSERT_EQ(0, function_->scope()->ContextChainLength(var->scope()));
441 } else if (decl->fun() != NULL) {
442 Visit(decl->fun());
443 } else {
444 __ Push(Smi::FromInt(0)); // no initial value!
445 }
446 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
447 break;
448 }
449 case Slot::LOCAL:
450 if (decl->mode() == Variable::CONST) {
451 __ Move(Operand(rbp, SlotOffset(var->slot())),
452 Factory::the_hole_value());
453 } else if (decl->fun() != NULL) {
454 Visit(decl->fun());
455 __ pop(Operand(rbp, SlotOffset(var->slot())));
456 }
457 break;
458 case Slot::CONTEXT:
459 // The variable in the decl always resides in the current context.
460 ASSERT(function_->scope()->ContextChainLength(slot->var()->scope()) == 0);
461 if (decl->mode() == Variable::CONST) {
462 __ Move(rax, Factory::the_hole_value());
463 if (FLAG_debug_code) { 441 if (FLAG_debug_code) {
464 // Check if we have the correct context pointer. 442 // Check if we have the correct context pointer.
465 __ movq(rbx, CodeGenerator::ContextOperand(rsi, 443 __ movq(rbx,
466 Context::FCONTEXT_INDEX)); 444 CodeGenerator::ContextOperand(rsi, Context::FCONTEXT_INDEX));
467 __ cmpq(rbx, rsi); 445 __ cmpq(rbx, rsi);
468 __ Check(equal, "Unexpected declaration in current context."); 446 __ Check(equal, "Unexpected declaration in current context.");
469 } 447 }
470 __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax); 448 if (decl->mode() == Variable::CONST) {
471 // No write barrier since the_hole_value is in old space. 449 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
472 ASSERT(!Heap::InNewSpace(*Factory::the_hole_value())); 450 __ movq(CodeGenerator::ContextOperand(rsi, slot->index()),
473 } else if (decl->fun() != NULL) { 451 kScratchRegister);
452 // No write barrier since the hole value is in old space.
453 } else if (decl->fun() != NULL) {
454 Visit(decl->fun());
455 __ pop(rax);
456 __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax);
457 int offset = Context::SlotOffset(slot->index());
458 __ RecordWrite(rsi, offset, rax, rcx);
459 }
460 break;
461
462 case Slot::LOOKUP: {
463 __ push(rsi);
464 __ Push(var->name());
465 // Declaration nodes are always introduced in one of two modes.
466 ASSERT(decl->mode() == Variable::VAR ||
467 decl->mode() == Variable::CONST);
468 PropertyAttributes attr =
469 (decl->mode() == Variable::VAR) ? NONE : READ_ONLY;
470 __ Push(Smi::FromInt(attr));
471 // Push initial value, if any.
472 // Note: For variables we must not push an initial value (such as
473 // 'undefined') because we may have a (legal) redeclaration and we
474 // must not destroy the current value.
475 if (decl->mode() == Variable::CONST) {
476 __ PushRoot(Heap::kTheHoleValueRootIndex);
477 } else if (decl->fun() != NULL) {
478 Visit(decl->fun());
479 } else {
480 __ Push(Smi::FromInt(0)); // no initial value!
481 }
482 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
483 break;
484 }
485 }
486
487 } else if (prop != NULL) {
488 if (decl->fun() != NULL || decl->mode() == Variable::CONST) {
489 // We are declaring a function or constant that rewrites to a
490 // property. Use (keyed) IC to set the initial value.
491 ASSERT_EQ(Expression::kValue, prop->obj()->context());
492 Visit(prop->obj());
493 ASSERT_EQ(Expression::kValue, prop->key()->context());
494 Visit(prop->key());
495
496 if (decl->fun() != NULL) {
497 ASSERT_EQ(Expression::kValue, decl->fun()->context());
474 Visit(decl->fun()); 498 Visit(decl->fun());
475 __ pop(rax); 499 __ pop(rax);
476 if (FLAG_debug_code) { 500 } else {
477 // Check if we have the correct context pointer. 501 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
478 __ movq(rbx, CodeGenerator::ContextOperand(rsi,
479 Context::FCONTEXT_INDEX));
480 __ cmpq(rbx, rsi);
481 __ Check(equal, "Unexpected declaration in current context.");
482 }
483 __ movq(CodeGenerator::ContextOperand(rsi, slot->index()), rax);
484 int offset = Context::SlotOffset(slot->index());
485 __ RecordWrite(rsi, offset, rax, rcx);
486 } 502 }
487 break; 503
488 default: 504 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
489 UNREACHABLE(); 505 __ call(ic, RelocInfo::CODE_TARGET);
506
507 // Absence of a test rax instruction following the call
508 // indicates that none of the load was inlined.
509
510 // Value in rax is ignored (declarations are statements). Receiver
511 // and key on stack are discarded.
512 __ addq(rsp, Immediate(2 * kPointerSize));
513 }
490 } 514 }
491 } 515 }
492 516
493 517
494 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 518 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
495 // Call the runtime to declare the globals. 519 // Call the runtime to declare the globals.
496 __ push(rsi); // The context is the first argument. 520 __ push(rsi); // The context is the first argument.
497 __ Push(pairs); 521 __ Push(pairs);
498 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); 522 __ Push(Smi::FromInt(is_eval_ ? 1 : 0));
499 __ CallRuntime(Runtime::kDeclareGlobals, 3); 523 __ CallRuntime(Runtime::kDeclareGlobals, 3);
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 true_label_ = saved_true; 1705 true_label_ = saved_true;
1682 false_label_ = saved_false; 1706 false_label_ = saved_false;
1683 // Convert current context to test context: End post-test code. 1707 // Convert current context to test context: End post-test code.
1684 } 1708 }
1685 1709
1686 1710
1687 #undef __ 1711 #undef __
1688 1712
1689 1713
1690 } } // namespace v8::internal 1714 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/version.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698