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

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

Issue 549108: Rename the toplevel code generator from "Fast" to "Full". It was... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/codegen-x64.h ('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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // formal parameter count expected by the function. 44 // formal parameter count expected by the function.
45 // 45 //
46 // The live registers are: 46 // The live registers are:
47 // o rdi: the JS function object being called (ie, ourselves) 47 // o rdi: the JS function object being called (ie, ourselves)
48 // o rsi: our context 48 // o rsi: our context
49 // o rbp: our caller's frame pointer 49 // o rbp: our caller's frame pointer
50 // o rsp: stack pointer (pointing to return address) 50 // o rsp: stack pointer (pointing to return address)
51 // 51 //
52 // The function builds a JS frame. Please see JavaScriptFrameConstants in 52 // The function builds a JS frame. Please see JavaScriptFrameConstants in
53 // frames-x64.h for its layout. 53 // frames-x64.h for its layout.
54 void FastCodeGenerator::Generate(FunctionLiteral* fun) { 54 void FullCodeGenerator::Generate(FunctionLiteral* fun) {
55 function_ = fun; 55 function_ = fun;
56 SetFunctionPosition(fun); 56 SetFunctionPosition(fun);
57 57
58 __ push(rbp); // Caller's frame pointer. 58 __ push(rbp); // Caller's frame pointer.
59 __ movq(rbp, rsp); 59 __ movq(rbp, rsp);
60 __ push(rsi); // Callee's context. 60 __ push(rsi); // Callee's context.
61 __ push(rdi); // Callee's JS Function. 61 __ push(rdi); // Callee's JS Function.
62 62
63 { Comment cmnt(masm_, "[ Allocate locals"); 63 { Comment cmnt(masm_, "[ Allocate locals");
64 int locals_count = fun->scope()->num_stack_slots(); 64 int locals_count = fun->scope()->num_stack_slots();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 154 }
155 155
156 { Comment cmnt(masm_, "[ return <undefined>;"); 156 { Comment cmnt(masm_, "[ return <undefined>;");
157 // Emit a 'return undefined' in case control fell off the end of the body. 157 // Emit a 'return undefined' in case control fell off the end of the body.
158 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 158 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
159 EmitReturnSequence(function_->end_position()); 159 EmitReturnSequence(function_->end_position());
160 } 160 }
161 } 161 }
162 162
163 163
164 void FastCodeGenerator::EmitReturnSequence(int position) { 164 void FullCodeGenerator::EmitReturnSequence(int position) {
165 Comment cmnt(masm_, "[ Return sequence"); 165 Comment cmnt(masm_, "[ Return sequence");
166 if (return_label_.is_bound()) { 166 if (return_label_.is_bound()) {
167 __ jmp(&return_label_); 167 __ jmp(&return_label_);
168 } else { 168 } else {
169 __ bind(&return_label_); 169 __ bind(&return_label_);
170 if (FLAG_trace) { 170 if (FLAG_trace) {
171 __ push(rax); 171 __ push(rax);
172 __ CallRuntime(Runtime::kTraceExit, 1); 172 __ CallRuntime(Runtime::kTraceExit, 1);
173 } 173 }
174 #ifdef DEBUG 174 #ifdef DEBUG
(...skipping 18 matching lines...) Expand all
193 } 193 }
194 // Check that the size of the code used for returning matches what is 194 // Check that the size of the code used for returning matches what is
195 // expected by the debugger. 195 // expected by the debugger.
196 ASSERT_EQ(Assembler::kJSReturnSequenceLength, 196 ASSERT_EQ(Assembler::kJSReturnSequenceLength,
197 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 197 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
198 #endif 198 #endif
199 } 199 }
200 } 200 }
201 201
202 202
203 void FastCodeGenerator::Apply(Expression::Context context, Register reg) { 203 void FullCodeGenerator::Apply(Expression::Context context, Register reg) {
204 switch (context) { 204 switch (context) {
205 case Expression::kUninitialized: 205 case Expression::kUninitialized:
206 UNREACHABLE(); 206 UNREACHABLE();
207 207
208 case Expression::kEffect: 208 case Expression::kEffect:
209 // Nothing to do. 209 // Nothing to do.
210 break; 210 break;
211 211
212 case Expression::kValue: 212 case Expression::kValue:
213 // Move value into place. 213 // Move value into place.
(...skipping 22 matching lines...) Expand all
236 case kStack: 236 case kStack:
237 __ push(result_register()); 237 __ push(result_register());
238 break; 238 break;
239 } 239 }
240 DoTest(context); 240 DoTest(context);
241 break; 241 break;
242 } 242 }
243 } 243 }
244 244
245 245
246 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { 246 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
247 switch (context) { 247 switch (context) {
248 case Expression::kUninitialized: 248 case Expression::kUninitialized:
249 UNREACHABLE(); 249 UNREACHABLE();
250 case Expression::kEffect: 250 case Expression::kEffect:
251 // Nothing to do. 251 // Nothing to do.
252 break; 252 break;
253 case Expression::kValue: { 253 case Expression::kValue: {
254 MemOperand slot_operand = EmitSlotSearch(slot, result_register()); 254 MemOperand slot_operand = EmitSlotSearch(slot, result_register());
255 switch (location_) { 255 switch (location_) {
256 case kAccumulator: 256 case kAccumulator:
(...skipping 21 matching lines...) Expand all
278 case kStack: 278 case kStack:
279 __ push(result_register()); 279 __ push(result_register());
280 break; 280 break;
281 } 281 }
282 DoTest(context); 282 DoTest(context);
283 break; 283 break;
284 } 284 }
285 } 285 }
286 286
287 287
288 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { 288 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
289 switch (context) { 289 switch (context) {
290 case Expression::kUninitialized: 290 case Expression::kUninitialized:
291 UNREACHABLE(); 291 UNREACHABLE();
292 case Expression::kEffect: 292 case Expression::kEffect:
293 // Nothing to do. 293 // Nothing to do.
294 break; 294 break;
295 case Expression::kValue: 295 case Expression::kValue:
296 switch (location_) { 296 switch (location_) {
297 case kAccumulator: 297 case kAccumulator:
298 __ Move(result_register(), lit->handle()); 298 __ Move(result_register(), lit->handle());
(...skipping 18 matching lines...) Expand all
317 case kStack: 317 case kStack:
318 __ push(result_register()); 318 __ push(result_register());
319 break; 319 break;
320 } 320 }
321 DoTest(context); 321 DoTest(context);
322 break; 322 break;
323 } 323 }
324 } 324 }
325 325
326 326
327 void FastCodeGenerator::ApplyTOS(Expression::Context context) { 327 void FullCodeGenerator::ApplyTOS(Expression::Context context) {
328 switch (context) { 328 switch (context) {
329 case Expression::kUninitialized: 329 case Expression::kUninitialized:
330 UNREACHABLE(); 330 UNREACHABLE();
331 331
332 case Expression::kEffect: 332 case Expression::kEffect:
333 __ Drop(1); 333 __ Drop(1);
334 break; 334 break;
335 335
336 case Expression::kValue: 336 case Expression::kValue:
337 switch (location_) { 337 switch (location_) {
(...skipping 19 matching lines...) Expand all
357 case kStack: 357 case kStack:
358 __ movq(result_register(), Operand(rsp, 0)); 358 __ movq(result_register(), Operand(rsp, 0));
359 break; 359 break;
360 } 360 }
361 DoTest(context); 361 DoTest(context);
362 break; 362 break;
363 } 363 }
364 } 364 }
365 365
366 366
367 void FastCodeGenerator::DropAndApply(int count, 367 void FullCodeGenerator::DropAndApply(int count,
368 Expression::Context context, 368 Expression::Context context,
369 Register reg) { 369 Register reg) {
370 ASSERT(count > 0); 370 ASSERT(count > 0);
371 ASSERT(!reg.is(rsp)); 371 ASSERT(!reg.is(rsp));
372 switch (context) { 372 switch (context) {
373 case Expression::kUninitialized: 373 case Expression::kUninitialized:
374 UNREACHABLE(); 374 UNREACHABLE();
375 375
376 case Expression::kEffect: 376 case Expression::kEffect:
377 __ Drop(count); 377 __ Drop(count);
(...skipping 30 matching lines...) Expand all
408 __ movq(result_register(), reg); 408 __ movq(result_register(), reg);
409 __ movq(Operand(rsp, 0), result_register()); 409 __ movq(Operand(rsp, 0), result_register());
410 break; 410 break;
411 } 411 }
412 DoTest(context); 412 DoTest(context);
413 break; 413 break;
414 } 414 }
415 } 415 }
416 416
417 417
418 void FastCodeGenerator::Apply(Expression::Context context, 418 void FullCodeGenerator::Apply(Expression::Context context,
419 Label* materialize_true, 419 Label* materialize_true,
420 Label* materialize_false) { 420 Label* materialize_false) {
421 switch (context) { 421 switch (context) {
422 case Expression::kUninitialized: 422 case Expression::kUninitialized:
423 423
424 case Expression::kEffect: 424 case Expression::kEffect:
425 ASSERT_EQ(materialize_true, materialize_false); 425 ASSERT_EQ(materialize_true, materialize_false);
426 __ bind(materialize_true); 426 __ bind(materialize_true);
427 break; 427 break;
428 428
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 case kStack: 473 case kStack:
474 __ Push(Factory::false_value()); 474 __ Push(Factory::false_value());
475 break; 475 break;
476 } 476 }
477 __ jmp(false_label_); 477 __ jmp(false_label_);
478 break; 478 break;
479 } 479 }
480 } 480 }
481 481
482 482
483 void FastCodeGenerator::DoTest(Expression::Context context) { 483 void FullCodeGenerator::DoTest(Expression::Context context) {
484 // The value to test is in the accumulator. If the value might be needed 484 // The value to test is in the accumulator. If the value might be needed
485 // on the stack (value/test and test/value contexts with a stack location 485 // on the stack (value/test and test/value contexts with a stack location
486 // desired), then the value is already duplicated on the stack. 486 // desired), then the value is already duplicated on the stack.
487 ASSERT_NE(NULL, true_label_); 487 ASSERT_NE(NULL, true_label_);
488 ASSERT_NE(NULL, false_label_); 488 ASSERT_NE(NULL, false_label_);
489 489
490 // In value/test and test/value expression contexts with stack as the 490 // In value/test and test/value expression contexts with stack as the
491 // desired location, there is already an extra value on the stack. Use a 491 // desired location, there is already an extra value on the stack. Use a
492 // label to discard it if unneeded. 492 // label to discard it if unneeded.
493 Label discard; 493 Label discard;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 break; 607 break;
608 } 608 }
609 __ bind(&discard); 609 __ bind(&discard);
610 __ Drop(1); 610 __ Drop(1);
611 __ jmp(true_label_); 611 __ jmp(true_label_);
612 break; 612 break;
613 } 613 }
614 } 614 }
615 615
616 616
617 MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 617 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
618 switch (slot->type()) { 618 switch (slot->type()) {
619 case Slot::PARAMETER: 619 case Slot::PARAMETER:
620 case Slot::LOCAL: 620 case Slot::LOCAL:
621 return Operand(rbp, SlotOffset(slot)); 621 return Operand(rbp, SlotOffset(slot));
622 case Slot::CONTEXT: { 622 case Slot::CONTEXT: {
623 int context_chain_length = 623 int context_chain_length =
624 function_->scope()->ContextChainLength(slot->var()->scope()); 624 function_->scope()->ContextChainLength(slot->var()->scope());
625 __ LoadContext(scratch, context_chain_length); 625 __ LoadContext(scratch, context_chain_length);
626 return CodeGenerator::ContextOperand(scratch, slot->index()); 626 return CodeGenerator::ContextOperand(scratch, slot->index());
627 } 627 }
628 case Slot::LOOKUP: 628 case Slot::LOOKUP:
629 UNREACHABLE(); 629 UNREACHABLE();
630 } 630 }
631 UNREACHABLE(); 631 UNREACHABLE();
632 return Operand(rax, 0); 632 return Operand(rax, 0);
633 } 633 }
634 634
635 635
636 void FastCodeGenerator::Move(Register destination, Slot* source) { 636 void FullCodeGenerator::Move(Register destination, Slot* source) {
637 MemOperand location = EmitSlotSearch(source, destination); 637 MemOperand location = EmitSlotSearch(source, destination);
638 __ movq(destination, location); 638 __ movq(destination, location);
639 } 639 }
640 640
641 641
642 void FastCodeGenerator::Move(Slot* dst, 642 void FullCodeGenerator::Move(Slot* dst,
643 Register src, 643 Register src,
644 Register scratch1, 644 Register scratch1,
645 Register scratch2) { 645 Register scratch2) {
646 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. 646 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
647 ASSERT(!scratch1.is(src) && !scratch2.is(src)); 647 ASSERT(!scratch1.is(src) && !scratch2.is(src));
648 MemOperand location = EmitSlotSearch(dst, scratch1); 648 MemOperand location = EmitSlotSearch(dst, scratch1);
649 __ movq(location, src); 649 __ movq(location, src);
650 // Emit the write barrier code if the location is in the heap. 650 // Emit the write barrier code if the location is in the heap.
651 if (dst->type() == Slot::CONTEXT) { 651 if (dst->type() == Slot::CONTEXT) {
652 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize; 652 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
653 __ RecordWrite(scratch1, offset, src, scratch2); 653 __ RecordWrite(scratch1, offset, src, scratch2);
654 } 654 }
655 } 655 }
656 656
657 657
658 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { 658 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
659 Comment cmnt(masm_, "[ Declaration"); 659 Comment cmnt(masm_, "[ Declaration");
660 Variable* var = decl->proxy()->var(); 660 Variable* var = decl->proxy()->var();
661 ASSERT(var != NULL); // Must have been resolved. 661 ASSERT(var != NULL); // Must have been resolved.
662 Slot* slot = var->slot(); 662 Slot* slot = var->slot();
663 Property* prop = var->AsProperty(); 663 Property* prop = var->AsProperty();
664 664
665 if (slot != NULL) { 665 if (slot != NULL) {
666 switch (slot->type()) { 666 switch (slot->type()) {
667 case Slot::PARAMETER: 667 case Slot::PARAMETER:
668 case Slot::LOCAL: 668 case Slot::LOCAL:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 __ nop(); 747 __ nop();
748 748
749 // Value in rax is ignored (declarations are statements). Receiver 749 // Value in rax is ignored (declarations are statements). Receiver
750 // and key on stack are discarded. 750 // and key on stack are discarded.
751 __ Drop(2); 751 __ Drop(2);
752 } 752 }
753 } 753 }
754 } 754 }
755 755
756 756
757 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 757 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
758 // Call the runtime to declare the globals. 758 // Call the runtime to declare the globals.
759 __ push(rsi); // The context is the first argument. 759 __ push(rsi); // The context is the first argument.
760 __ Push(pairs); 760 __ Push(pairs);
761 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); 761 __ Push(Smi::FromInt(is_eval_ ? 1 : 0));
762 __ CallRuntime(Runtime::kDeclareGlobals, 3); 762 __ CallRuntime(Runtime::kDeclareGlobals, 3);
763 // Return value is ignored. 763 // Return value is ignored.
764 } 764 }
765 765
766 766
767 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 767 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
768 Comment cmnt(masm_, "[ FunctionLiteral"); 768 Comment cmnt(masm_, "[ FunctionLiteral");
769 769
770 // Build the function boilerplate and instantiate it. 770 // Build the function boilerplate and instantiate it.
771 Handle<JSFunction> boilerplate = 771 Handle<JSFunction> boilerplate =
772 Compiler::BuildBoilerplate(expr, script_, this); 772 Compiler::BuildBoilerplate(expr, script_, this);
773 if (HasStackOverflow()) return; 773 if (HasStackOverflow()) return;
774 774
775 ASSERT(boilerplate->IsBoilerplate()); 775 ASSERT(boilerplate->IsBoilerplate());
776 776
777 // Create a new closure. 777 // Create a new closure.
778 __ push(rsi); 778 __ push(rsi);
779 __ Push(boilerplate); 779 __ Push(boilerplate);
780 __ CallRuntime(Runtime::kNewClosure, 2); 780 __ CallRuntime(Runtime::kNewClosure, 2);
781 Apply(context_, rax); 781 Apply(context_, rax);
782 } 782 }
783 783
784 784
785 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 785 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
786 Comment cmnt(masm_, "[ VariableProxy"); 786 Comment cmnt(masm_, "[ VariableProxy");
787 EmitVariableLoad(expr->var(), context_); 787 EmitVariableLoad(expr->var(), context_);
788 } 788 }
789 789
790 790
791 void FastCodeGenerator::EmitVariableLoad(Variable* var, 791 void FullCodeGenerator::EmitVariableLoad(Variable* var,
792 Expression::Context context) { 792 Expression::Context context) {
793 Expression* rewrite = var->rewrite(); 793 Expression* rewrite = var->rewrite();
794 if (rewrite == NULL) { 794 if (rewrite == NULL) {
795 ASSERT(var->is_global()); 795 ASSERT(var->is_global());
796 Comment cmnt(masm_, "Global variable"); 796 Comment cmnt(masm_, "Global variable");
797 // Use inline caching. Variable name is passed in rcx and the global 797 // Use inline caching. Variable name is passed in rcx and the global
798 // object on the stack. 798 // object on the stack.
799 __ push(CodeGenerator::GlobalObject()); 799 __ push(CodeGenerator::GlobalObject());
800 __ Move(rcx, var->name()); 800 __ Move(rcx, var->name());
801 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 801 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 __ call(ic, RelocInfo::CODE_TARGET); 857 __ call(ic, RelocInfo::CODE_TARGET);
858 // Notice: We must not have a "test rax, ..." instruction after the 858 // Notice: We must not have a "test rax, ..." instruction after the
859 // call. It is treated specially by the LoadIC code. 859 // call. It is treated specially by the LoadIC code.
860 __ nop(); 860 __ nop();
861 // Drop key and object left on the stack by IC, and push the result. 861 // Drop key and object left on the stack by IC, and push the result.
862 DropAndApply(2, context, rax); 862 DropAndApply(2, context, rax);
863 } 863 }
864 } 864 }
865 865
866 866
867 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 867 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
868 Comment cmnt(masm_, "[ RegExpLiteral"); 868 Comment cmnt(masm_, "[ RegExpLiteral");
869 Label done; 869 Label done;
870 // Registers will be used as follows: 870 // Registers will be used as follows:
871 // rdi = JS function. 871 // rdi = JS function.
872 // rbx = literals array. 872 // rbx = literals array.
873 // rax = regexp literal. 873 // rax = regexp literal.
874 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 874 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
875 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); 875 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
876 int literal_offset = 876 int literal_offset =
877 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 877 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
878 __ movq(rax, FieldOperand(rbx, literal_offset)); 878 __ movq(rax, FieldOperand(rbx, literal_offset));
879 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 879 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
880 __ j(not_equal, &done); 880 __ j(not_equal, &done);
881 // Create regexp literal using runtime function 881 // Create regexp literal using runtime function
882 // Result will be in rax. 882 // Result will be in rax.
883 __ push(rbx); 883 __ push(rbx);
884 __ Push(Smi::FromInt(expr->literal_index())); 884 __ Push(Smi::FromInt(expr->literal_index()));
885 __ Push(expr->pattern()); 885 __ Push(expr->pattern());
886 __ Push(expr->flags()); 886 __ Push(expr->flags());
887 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 887 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
888 __ bind(&done); 888 __ bind(&done);
889 Apply(context_, rax); 889 Apply(context_, rax);
890 } 890 }
891 891
892 892
893 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 893 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
894 Comment cmnt(masm_, "[ ObjectLiteral"); 894 Comment cmnt(masm_, "[ ObjectLiteral");
895 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 895 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
896 __ push(FieldOperand(rdi, JSFunction::kLiteralsOffset)); 896 __ push(FieldOperand(rdi, JSFunction::kLiteralsOffset));
897 __ Push(Smi::FromInt(expr->literal_index())); 897 __ Push(Smi::FromInt(expr->literal_index()));
898 __ Push(expr->constant_properties()); 898 __ Push(expr->constant_properties());
899 if (expr->depth() > 1) { 899 if (expr->depth() > 1) {
900 __ CallRuntime(Runtime::kCreateObjectLiteral, 3); 900 __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
901 } else { 901 } else {
902 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3); 902 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
903 } 903 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 } 953 }
954 954
955 if (result_saved) { 955 if (result_saved) {
956 ApplyTOS(context_); 956 ApplyTOS(context_);
957 } else { 957 } else {
958 Apply(context_, rax); 958 Apply(context_, rax);
959 } 959 }
960 } 960 }
961 961
962 962
963 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 963 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
964 Comment cmnt(masm_, "[ ArrayLiteral"); 964 Comment cmnt(masm_, "[ ArrayLiteral");
965 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 965 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
966 __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); 966 __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
967 __ Push(Smi::FromInt(expr->literal_index())); 967 __ Push(Smi::FromInt(expr->literal_index()));
968 __ Push(expr->constant_elements()); 968 __ Push(expr->constant_elements());
969 if (expr->depth() > 1) { 969 if (expr->depth() > 1) {
970 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 970 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
971 } else { 971 } else {
972 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 972 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
973 } 973 }
(...skipping 29 matching lines...) Expand all
1003 } 1003 }
1004 1004
1005 if (result_saved) { 1005 if (result_saved) {
1006 ApplyTOS(context_); 1006 ApplyTOS(context_);
1007 } else { 1007 } else {
1008 Apply(context_, rax); 1008 Apply(context_, rax);
1009 } 1009 }
1010 } 1010 }
1011 1011
1012 1012
1013 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1013 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1014 SetSourcePosition(prop->position()); 1014 SetSourcePosition(prop->position());
1015 Literal* key = prop->key()->AsLiteral(); 1015 Literal* key = prop->key()->AsLiteral();
1016 __ Move(rcx, key->handle()); 1016 __ Move(rcx, key->handle());
1017 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1017 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1018 __ Call(ic, RelocInfo::CODE_TARGET); 1018 __ Call(ic, RelocInfo::CODE_TARGET);
1019 __ nop(); 1019 __ nop();
1020 } 1020 }
1021 1021
1022 1022
1023 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1023 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1024 SetSourcePosition(prop->position()); 1024 SetSourcePosition(prop->position());
1025 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1025 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1026 __ Call(ic, RelocInfo::CODE_TARGET); 1026 __ Call(ic, RelocInfo::CODE_TARGET);
1027 __ nop(); 1027 __ nop();
1028 } 1028 }
1029 1029
1030 1030
1031 void FastCodeGenerator::EmitBinaryOp(Token::Value op, 1031 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1032 Expression::Context context) { 1032 Expression::Context context) {
1033 __ push(result_register()); 1033 __ push(result_register());
1034 GenericBinaryOpStub stub(op, 1034 GenericBinaryOpStub stub(op,
1035 NO_OVERWRITE, 1035 NO_OVERWRITE,
1036 NO_GENERIC_BINARY_FLAGS); 1036 NO_GENERIC_BINARY_FLAGS);
1037 __ CallStub(&stub); 1037 __ CallStub(&stub);
1038 Apply(context, rax); 1038 Apply(context, rax);
1039 } 1039 }
1040 1040
1041 1041
1042 void FastCodeGenerator::EmitVariableAssignment(Variable* var, 1042 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1043 Expression::Context context) { 1043 Expression::Context context) {
1044 ASSERT(var != NULL); 1044 ASSERT(var != NULL);
1045 ASSERT(var->is_global() || var->slot() != NULL); 1045 ASSERT(var->is_global() || var->slot() != NULL);
1046 if (var->is_global()) { 1046 if (var->is_global()) {
1047 // Assignment to a global variable. Use inline caching for the 1047 // Assignment to a global variable. Use inline caching for the
1048 // assignment. Right-hand-side value is passed in rax, variable name in 1048 // assignment. Right-hand-side value is passed in rax, variable name in
1049 // rcx, and the global object on the stack. 1049 // rcx, and the global object on the stack.
1050 __ Move(rcx, var->name()); 1050 __ Move(rcx, var->name());
1051 __ push(CodeGenerator::GlobalObject()); 1051 __ push(CodeGenerator::GlobalObject());
1052 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1052 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
(...skipping 26 matching lines...) Expand all
1079 } 1079 }
1080 Apply(context, result_register()); 1080 Apply(context, result_register());
1081 } else { 1081 } else {
1082 // Variables rewritten as properties are not treated as variables in 1082 // Variables rewritten as properties are not treated as variables in
1083 // assignments. 1083 // assignments.
1084 UNREACHABLE(); 1084 UNREACHABLE();
1085 } 1085 }
1086 } 1086 }
1087 1087
1088 1088
1089 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1089 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1090 // Assignment to a property, using a named store IC. 1090 // Assignment to a property, using a named store IC.
1091 Property* prop = expr->target()->AsProperty(); 1091 Property* prop = expr->target()->AsProperty();
1092 ASSERT(prop != NULL); 1092 ASSERT(prop != NULL);
1093 ASSERT(prop->key()->AsLiteral() != NULL); 1093 ASSERT(prop->key()->AsLiteral() != NULL);
1094 1094
1095 // If the assignment starts a block of assignments to the same object, 1095 // If the assignment starts a block of assignments to the same object,
1096 // change to slow case to avoid the quadratic behavior of repeatedly 1096 // change to slow case to avoid the quadratic behavior of repeatedly
1097 // adding fast properties. 1097 // adding fast properties.
1098 if (expr->starts_initialization_block()) { 1098 if (expr->starts_initialization_block()) {
1099 __ push(result_register()); 1099 __ push(result_register());
(...skipping 14 matching lines...) Expand all
1114 __ push(rax); // Result of assignment, saved even if not needed. 1114 __ push(rax); // Result of assignment, saved even if not needed.
1115 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1115 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1116 __ CallRuntime(Runtime::kToFastProperties, 1); 1116 __ CallRuntime(Runtime::kToFastProperties, 1);
1117 __ pop(rax); 1117 __ pop(rax);
1118 } 1118 }
1119 1119
1120 DropAndApply(1, context_, rax); 1120 DropAndApply(1, context_, rax);
1121 } 1121 }
1122 1122
1123 1123
1124 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1124 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1125 // Assignment to a property, using a keyed store IC. 1125 // Assignment to a property, using a keyed store IC.
1126 1126
1127 // If the assignment starts a block of assignments to the same object, 1127 // If the assignment starts a block of assignments to the same object,
1128 // change to slow case to avoid the quadratic behavior of repeatedly 1128 // change to slow case to avoid the quadratic behavior of repeatedly
1129 // adding fast properties. 1129 // adding fast properties.
1130 if (expr->starts_initialization_block()) { 1130 if (expr->starts_initialization_block()) {
1131 __ push(result_register()); 1131 __ push(result_register());
1132 // Receiver is now under the key and value. 1132 // Receiver is now under the key and value.
1133 __ push(Operand(rsp, 2 * kPointerSize)); 1133 __ push(Operand(rsp, 2 * kPointerSize));
1134 __ CallRuntime(Runtime::kToSlowProperties, 1); 1134 __ CallRuntime(Runtime::kToSlowProperties, 1);
(...skipping 15 matching lines...) Expand all
1150 __ push(Operand(rsp, 2 * kPointerSize)); 1150 __ push(Operand(rsp, 2 * kPointerSize));
1151 __ CallRuntime(Runtime::kToFastProperties, 1); 1151 __ CallRuntime(Runtime::kToFastProperties, 1);
1152 __ pop(rax); 1152 __ pop(rax);
1153 } 1153 }
1154 1154
1155 // Receiver and key are still on stack. 1155 // Receiver and key are still on stack.
1156 DropAndApply(2, context_, rax); 1156 DropAndApply(2, context_, rax);
1157 } 1157 }
1158 1158
1159 1159
1160 void FastCodeGenerator::VisitProperty(Property* expr) { 1160 void FullCodeGenerator::VisitProperty(Property* expr) {
1161 Comment cmnt(masm_, "[ Property"); 1161 Comment cmnt(masm_, "[ Property");
1162 Expression* key = expr->key(); 1162 Expression* key = expr->key();
1163 1163
1164 // Evaluate receiver. 1164 // Evaluate receiver.
1165 VisitForValue(expr->obj(), kStack); 1165 VisitForValue(expr->obj(), kStack);
1166 1166
1167 if (key->IsPropertyName()) { 1167 if (key->IsPropertyName()) {
1168 EmitNamedPropertyLoad(expr); 1168 EmitNamedPropertyLoad(expr);
1169 // Drop receiver left on the stack by IC. 1169 // Drop receiver left on the stack by IC.
1170 DropAndApply(1, context_, rax); 1170 DropAndApply(1, context_, rax);
1171 } else { 1171 } else {
1172 VisitForValue(expr->key(), kStack); 1172 VisitForValue(expr->key(), kStack);
1173 EmitKeyedPropertyLoad(expr); 1173 EmitKeyedPropertyLoad(expr);
1174 // Drop key and receiver left on the stack by IC. 1174 // Drop key and receiver left on the stack by IC.
1175 DropAndApply(2, context_, rax); 1175 DropAndApply(2, context_, rax);
1176 } 1176 }
1177 } 1177 }
1178 1178
1179 1179
1180 void FastCodeGenerator::EmitCallWithIC(Call* expr, 1180 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1181 Handle<Object> ignored, 1181 Handle<Object> ignored,
1182 RelocInfo::Mode mode) { 1182 RelocInfo::Mode mode) {
1183 // Code common for calls using the IC. 1183 // Code common for calls using the IC.
1184 ZoneList<Expression*>* args = expr->arguments(); 1184 ZoneList<Expression*>* args = expr->arguments();
1185 int arg_count = args->length(); 1185 int arg_count = args->length();
1186 for (int i = 0; i < arg_count; i++) { 1186 for (int i = 0; i < arg_count; i++) {
1187 VisitForValue(args->at(i), kStack); 1187 VisitForValue(args->at(i), kStack);
1188 } 1188 }
1189 // Record source position for debugger. 1189 // Record source position for debugger.
1190 SetSourcePosition(expr->position()); 1190 SetSourcePosition(expr->position());
1191 // Call the IC initialization code. 1191 // Call the IC initialization code.
1192 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1192 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1193 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1193 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1194 in_loop); 1194 in_loop);
1195 __ Call(ic, mode); 1195 __ Call(ic, mode);
1196 // Restore context register. 1196 // Restore context register.
1197 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1197 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1198 // Discard the function left on TOS. 1198 // Discard the function left on TOS.
1199 DropAndApply(1, context_, rax); 1199 DropAndApply(1, context_, rax);
1200 } 1200 }
1201 1201
1202 1202
1203 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1203 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1204 // Code common for calls using the call stub. 1204 // Code common for calls using the call stub.
1205 ZoneList<Expression*>* args = expr->arguments(); 1205 ZoneList<Expression*>* args = expr->arguments();
1206 int arg_count = args->length(); 1206 int arg_count = args->length();
1207 for (int i = 0; i < arg_count; i++) { 1207 for (int i = 0; i < arg_count; i++) {
1208 VisitForValue(args->at(i), kStack); 1208 VisitForValue(args->at(i), kStack);
1209 } 1209 }
1210 // Record source position for debugger. 1210 // Record source position for debugger.
1211 SetSourcePosition(expr->position()); 1211 SetSourcePosition(expr->position());
1212 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); 1212 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
1213 __ CallStub(&stub); 1213 __ CallStub(&stub);
1214 // Restore context register. 1214 // Restore context register.
1215 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1215 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1216 // Discard the function left on TOS. 1216 // Discard the function left on TOS.
1217 DropAndApply(1, context_, rax); 1217 DropAndApply(1, context_, rax);
1218 } 1218 }
1219 1219
1220 1220
1221 void FastCodeGenerator::VisitCall(Call* expr) { 1221 void FullCodeGenerator::VisitCall(Call* expr) {
1222 Comment cmnt(masm_, "[ Call"); 1222 Comment cmnt(masm_, "[ Call");
1223 Expression* fun = expr->expression(); 1223 Expression* fun = expr->expression();
1224 Variable* var = fun->AsVariableProxy()->AsVariable(); 1224 Variable* var = fun->AsVariableProxy()->AsVariable();
1225 1225
1226 if (var != NULL && var->is_possibly_eval()) { 1226 if (var != NULL && var->is_possibly_eval()) {
1227 // Call to the identifier 'eval'. 1227 // Call to the identifier 'eval'.
1228 UNREACHABLE(); 1228 UNREACHABLE();
1229 } else if (var != NULL && !var->is_this() && var->is_global()) { 1229 } else if (var != NULL && !var->is_this() && var->is_global()) {
1230 // Call to a global variable. 1230 // Call to a global variable.
1231 __ Push(var->name()); 1231 __ Push(var->name());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 VisitForValue(fun, kStack); 1285 VisitForValue(fun, kStack);
1286 // Load global receiver object. 1286 // Load global receiver object.
1287 __ movq(rbx, CodeGenerator::GlobalObject()); 1287 __ movq(rbx, CodeGenerator::GlobalObject());
1288 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); 1288 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
1289 // Emit function call. 1289 // Emit function call.
1290 EmitCallWithStub(expr); 1290 EmitCallWithStub(expr);
1291 } 1291 }
1292 } 1292 }
1293 1293
1294 1294
1295 void FastCodeGenerator::VisitCallNew(CallNew* expr) { 1295 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
1296 Comment cmnt(masm_, "[ CallNew"); 1296 Comment cmnt(masm_, "[ CallNew");
1297 // According to ECMA-262, section 11.2.2, page 44, the function 1297 // According to ECMA-262, section 11.2.2, page 44, the function
1298 // expression in new calls must be evaluated before the 1298 // expression in new calls must be evaluated before the
1299 // arguments. 1299 // arguments.
1300 // Push function on the stack. 1300 // Push function on the stack.
1301 VisitForValue(expr->expression(), kStack); 1301 VisitForValue(expr->expression(), kStack);
1302 1302
1303 // Push global object (receiver). 1303 // Push global object (receiver).
1304 __ push(CodeGenerator::GlobalObject()); 1304 __ push(CodeGenerator::GlobalObject());
1305 1305
(...skipping 14 matching lines...) Expand all
1320 __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize)); 1320 __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize));
1321 1321
1322 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1322 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1323 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1323 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1324 1324
1325 // Replace function on TOS with result in rax, or pop it. 1325 // Replace function on TOS with result in rax, or pop it.
1326 DropAndApply(1, context_, rax); 1326 DropAndApply(1, context_, rax);
1327 } 1327 }
1328 1328
1329 1329
1330 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1330 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1331 Comment cmnt(masm_, "[ CallRuntime"); 1331 Comment cmnt(masm_, "[ CallRuntime");
1332 ZoneList<Expression*>* args = expr->arguments(); 1332 ZoneList<Expression*>* args = expr->arguments();
1333 1333
1334 if (expr->is_jsruntime()) { 1334 if (expr->is_jsruntime()) {
1335 // Prepare for calling JS runtime function. 1335 // Prepare for calling JS runtime function.
1336 __ Push(expr->name()); 1336 __ Push(expr->name());
1337 __ movq(rax, CodeGenerator::GlobalObject()); 1337 __ movq(rax, CodeGenerator::GlobalObject());
1338 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); 1338 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
1339 } 1339 }
1340 1340
(...skipping 12 matching lines...) Expand all
1353 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1353 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1354 // Discard the function left on TOS. 1354 // Discard the function left on TOS.
1355 DropAndApply(1, context_, rax); 1355 DropAndApply(1, context_, rax);
1356 } else { 1356 } else {
1357 __ CallRuntime(expr->function(), arg_count); 1357 __ CallRuntime(expr->function(), arg_count);
1358 Apply(context_, rax); 1358 Apply(context_, rax);
1359 } 1359 }
1360 } 1360 }
1361 1361
1362 1362
1363 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 1363 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1364 switch (expr->op()) { 1364 switch (expr->op()) {
1365 case Token::VOID: { 1365 case Token::VOID: {
1366 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 1366 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1367 VisitForEffect(expr->expression()); 1367 VisitForEffect(expr->expression());
1368 switch (context_) { 1368 switch (context_) {
1369 case Expression::kUninitialized: 1369 case Expression::kUninitialized:
1370 UNREACHABLE(); 1370 UNREACHABLE();
1371 break; 1371 break;
1372 case Expression::kEffect: 1372 case Expression::kEffect:
1373 break; 1373 break;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 Apply(context_, rax); 1463 Apply(context_, rax);
1464 break; 1464 break;
1465 } 1465 }
1466 1466
1467 default: 1467 default:
1468 UNREACHABLE(); 1468 UNREACHABLE();
1469 } 1469 }
1470 } 1470 }
1471 1471
1472 1472
1473 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 1473 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1474 Comment cmnt(masm_, "[ CountOperation"); 1474 Comment cmnt(masm_, "[ CountOperation");
1475 1475
1476 // Expression can only be a property, a global or a (parameter or local) 1476 // Expression can only be a property, a global or a (parameter or local)
1477 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1477 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
1478 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1478 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1479 LhsKind assign_type = VARIABLE; 1479 LhsKind assign_type = VARIABLE;
1480 Property* prop = expr->expression()->AsProperty(); 1480 Property* prop = expr->expression()->AsProperty();
1481 // In case of a property we use the uninitialized expression context 1481 // In case of a property we use the uninitialized expression context
1482 // of the key to detect a named property. 1482 // of the key to detect a named property.
1483 if (prop != NULL) { 1483 if (prop != NULL) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 ApplyTOS(context_); 1594 ApplyTOS(context_);
1595 } 1595 }
1596 } else { 1596 } else {
1597 DropAndApply(2, context_, rax); 1597 DropAndApply(2, context_, rax);
1598 } 1598 }
1599 break; 1599 break;
1600 } 1600 }
1601 } 1601 }
1602 } 1602 }
1603 1603
1604 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 1604 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
1605 Comment cmnt(masm_, "[ BinaryOperation"); 1605 Comment cmnt(masm_, "[ BinaryOperation");
1606 switch (expr->op()) { 1606 switch (expr->op()) {
1607 case Token::COMMA: 1607 case Token::COMMA:
1608 VisitForEffect(expr->left()); 1608 VisitForEffect(expr->left());
1609 Visit(expr->right()); 1609 Visit(expr->right());
1610 break; 1610 break;
1611 1611
1612 case Token::OR: 1612 case Token::OR:
1613 case Token::AND: 1613 case Token::AND:
1614 EmitLogicalOperation(expr); 1614 EmitLogicalOperation(expr);
(...skipping 14 matching lines...) Expand all
1629 VisitForValue(expr->right(), kAccumulator); 1629 VisitForValue(expr->right(), kAccumulator);
1630 EmitBinaryOp(expr->op(), context_); 1630 EmitBinaryOp(expr->op(), context_);
1631 break; 1631 break;
1632 1632
1633 default: 1633 default:
1634 UNREACHABLE(); 1634 UNREACHABLE();
1635 } 1635 }
1636 } 1636 }
1637 1637
1638 1638
1639 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1639 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1640 Comment cmnt(masm_, "[ CompareOperation"); 1640 Comment cmnt(masm_, "[ CompareOperation");
1641 1641
1642 // Always perform the comparison for its control flow. Pack the result 1642 // Always perform the comparison for its control flow. Pack the result
1643 // into the expression's context after the comparison is performed. 1643 // into the expression's context after the comparison is performed.
1644 Label materialize_true, materialize_false, done; 1644 Label materialize_true, materialize_false, done;
1645 // Initially assume we are in a test context. 1645 // Initially assume we are in a test context.
1646 Label* if_true = true_label_; 1646 Label* if_true = true_label_;
1647 Label* if_false = false_label_; 1647 Label* if_false = false_label_;
1648 switch (context_) { 1648 switch (context_) {
1649 case Expression::kUninitialized: 1649 case Expression::kUninitialized:
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 __ jmp(if_false); 1741 __ jmp(if_false);
1742 } 1742 }
1743 } 1743 }
1744 1744
1745 // Convert the result of the comparison into one expected for this 1745 // Convert the result of the comparison into one expected for this
1746 // expression's context. 1746 // expression's context.
1747 Apply(context_, if_true, if_false); 1747 Apply(context_, if_true, if_false);
1748 } 1748 }
1749 1749
1750 1750
1751 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1751 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1752 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1752 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1753 Apply(context_, rax); 1753 Apply(context_, rax);
1754 } 1754 }
1755 1755
1756 1756
1757 Register FastCodeGenerator::result_register() { return rax; } 1757 Register FullCodeGenerator::result_register() { return rax; }
1758 1758
1759 1759
1760 Register FastCodeGenerator::context_register() { return rsi; } 1760 Register FullCodeGenerator::context_register() { return rsi; }
1761 1761
1762 1762
1763 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 1763 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
1764 ASSERT(IsAligned(frame_offset, kPointerSize)); 1764 ASSERT(IsAligned(frame_offset, kPointerSize));
1765 __ movq(Operand(rbp, frame_offset), value); 1765 __ movq(Operand(rbp, frame_offset), value);
1766 } 1766 }
1767 1767
1768 1768
1769 void FastCodeGenerator::LoadContextField(Register dst, int context_index) { 1769 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
1770 __ movq(dst, CodeGenerator::ContextOperand(rsi, context_index)); 1770 __ movq(dst, CodeGenerator::ContextOperand(rsi, context_index));
1771 } 1771 }
1772 1772
1773 1773
1774 // ---------------------------------------------------------------------------- 1774 // ----------------------------------------------------------------------------
1775 // Non-local control flow support. 1775 // Non-local control flow support.
1776 1776
1777 1777
1778 void FastCodeGenerator::EnterFinallyBlock() { 1778 void FullCodeGenerator::EnterFinallyBlock() {
1779 ASSERT(!result_register().is(rdx)); 1779 ASSERT(!result_register().is(rdx));
1780 ASSERT(!result_register().is(rcx)); 1780 ASSERT(!result_register().is(rcx));
1781 // Cook return address on top of stack (smi encoded Code* delta) 1781 // Cook return address on top of stack (smi encoded Code* delta)
1782 __ movq(rdx, Operand(rsp, 0)); 1782 __ movq(rdx, Operand(rsp, 0));
1783 __ Move(rcx, masm_->CodeObject()); 1783 __ Move(rcx, masm_->CodeObject());
1784 __ subq(rdx, rcx); 1784 __ subq(rdx, rcx);
1785 __ Integer32ToSmi(rdx, rdx); 1785 __ Integer32ToSmi(rdx, rdx);
1786 __ movq(Operand(rsp, 0), rdx); 1786 __ movq(Operand(rsp, 0), rdx);
1787 // Store result register while executing finally block. 1787 // Store result register while executing finally block.
1788 __ push(result_register()); 1788 __ push(result_register());
1789 } 1789 }
1790 1790
1791 1791
1792 void FastCodeGenerator::ExitFinallyBlock() { 1792 void FullCodeGenerator::ExitFinallyBlock() {
1793 ASSERT(!result_register().is(rdx)); 1793 ASSERT(!result_register().is(rdx));
1794 ASSERT(!result_register().is(rcx)); 1794 ASSERT(!result_register().is(rcx));
1795 // Restore result register from stack. 1795 // Restore result register from stack.
1796 __ pop(result_register()); 1796 __ pop(result_register());
1797 // Uncook return address. 1797 // Uncook return address.
1798 __ movq(rdx, Operand(rsp, 0)); 1798 __ movq(rdx, Operand(rsp, 0));
1799 __ SmiToInteger32(rdx, rdx); 1799 __ SmiToInteger32(rdx, rdx);
1800 __ Move(rcx, masm_->CodeObject()); 1800 __ Move(rcx, masm_->CodeObject());
1801 __ addq(rdx, rcx); 1801 __ addq(rdx, rcx);
1802 __ movq(Operand(rsp, 0), rdx); 1802 __ movq(Operand(rsp, 0), rdx);
1803 // And return. 1803 // And return.
1804 __ ret(0); 1804 __ ret(0);
1805 } 1805 }
1806 1806
1807 1807
1808 #undef __ 1808 #undef __
1809 1809
1810 1810
1811 } } // namespace v8::internal 1811 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698