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

Side by Side Diff: src/arm/fast-codegen-arm.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/arm/codegen-arm.h ('k') | src/compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 // 45 //
46 // The live registers are: 46 // The live registers are:
47 // o r1: the JS function object being called (ie, ourselves) 47 // o r1: the JS function object being called (ie, ourselves)
48 // o cp: our context 48 // o cp: our context
49 // o fp: our caller's frame pointer 49 // o fp: our caller's frame pointer
50 // o sp: stack pointer 50 // o sp: stack pointer
51 // o lr: return address 51 // o lr: return address
52 // 52 //
53 // The function builds a JS frame. Please see JavaScriptFrameConstants in 53 // The function builds a JS frame. Please see JavaScriptFrameConstants in
54 // frames-arm.h for its layout. 54 // frames-arm.h for its layout.
55 void FastCodeGenerator::Generate(FunctionLiteral* fun) { 55 void FullCodeGenerator::Generate(FunctionLiteral* fun) {
56 function_ = fun; 56 function_ = fun;
57 SetFunctionPosition(fun); 57 SetFunctionPosition(fun);
58 int locals_count = fun->scope()->num_stack_slots(); 58 int locals_count = fun->scope()->num_stack_slots();
59 59
60 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 60 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
61 if (locals_count > 0) { 61 if (locals_count > 0) {
62 // Load undefined value here, so the value is ready for the loop below. 62 // Load undefined value here, so the value is ready for the loop below.
63 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 63 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
64 } 64 }
65 // Adjust fp to point to caller's fp. 65 // Adjust fp to point to caller's fp.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 160
161 { Comment cmnt(masm_, "[ return <undefined>;"); 161 { Comment cmnt(masm_, "[ return <undefined>;");
162 // Emit a 'return undefined' in case control fell off the end of the 162 // Emit a 'return undefined' in case control fell off the end of the
163 // body. 163 // body.
164 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 164 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
165 } 165 }
166 EmitReturnSequence(function_->end_position()); 166 EmitReturnSequence(function_->end_position());
167 } 167 }
168 168
169 169
170 void FastCodeGenerator::EmitReturnSequence(int position) { 170 void FullCodeGenerator::EmitReturnSequence(int position) {
171 Comment cmnt(masm_, "[ Return sequence"); 171 Comment cmnt(masm_, "[ Return sequence");
172 if (return_label_.is_bound()) { 172 if (return_label_.is_bound()) {
173 __ b(&return_label_); 173 __ b(&return_label_);
174 } else { 174 } else {
175 __ bind(&return_label_); 175 __ bind(&return_label_);
176 if (FLAG_trace) { 176 if (FLAG_trace) {
177 // Push the return value on the stack as the parameter. 177 // Push the return value on the stack as the parameter.
178 // Runtime::TraceExit returns its parameter in r0. 178 // Runtime::TraceExit returns its parameter in r0.
179 __ push(r0); 179 __ push(r0);
180 __ CallRuntime(Runtime::kTraceExit, 1); 180 __ CallRuntime(Runtime::kTraceExit, 1);
(...skipping 26 matching lines...) Expand all
207 // mode 1 instruction where there are restrictions on which immediate values 207 // mode 1 instruction where there are restrictions on which immediate values
208 // can be encoded in the instruction and which immediate values requires 208 // can be encoded in the instruction and which immediate values requires
209 // use of an additional instruction for moving the immediate to a temporary 209 // use of an additional instruction for moving the immediate to a temporary
210 // register. 210 // register.
211 ASSERT_EQ(return_sequence_length, 211 ASSERT_EQ(return_sequence_length,
212 masm_->InstructionsGeneratedSince(&check_exit_codesize)); 212 masm_->InstructionsGeneratedSince(&check_exit_codesize));
213 } 213 }
214 } 214 }
215 215
216 216
217 void FastCodeGenerator::Apply(Expression::Context context, Register reg) { 217 void FullCodeGenerator::Apply(Expression::Context context, Register reg) {
218 switch (context) { 218 switch (context) {
219 case Expression::kUninitialized: 219 case Expression::kUninitialized:
220 UNREACHABLE(); 220 UNREACHABLE();
221 221
222 case Expression::kEffect: 222 case Expression::kEffect:
223 // Nothing to do. 223 // Nothing to do.
224 break; 224 break;
225 225
226 case Expression::kValue: 226 case Expression::kValue:
227 // Move value into place. 227 // Move value into place.
(...skipping 15 matching lines...) Expand all
243 243
244 case Expression::kTest: 244 case Expression::kTest:
245 // We always call the runtime on ARM, so push the value as argument. 245 // We always call the runtime on ARM, so push the value as argument.
246 __ push(reg); 246 __ push(reg);
247 DoTest(context); 247 DoTest(context);
248 break; 248 break;
249 } 249 }
250 } 250 }
251 251
252 252
253 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { 253 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
254 switch (context) { 254 switch (context) {
255 case Expression::kUninitialized: 255 case Expression::kUninitialized:
256 UNREACHABLE(); 256 UNREACHABLE();
257 case Expression::kEffect: 257 case Expression::kEffect:
258 // Nothing to do. 258 // Nothing to do.
259 break; 259 break;
260 case Expression::kValue: 260 case Expression::kValue:
261 case Expression::kTest: 261 case Expression::kTest:
262 case Expression::kValueTest: 262 case Expression::kValueTest:
263 case Expression::kTestValue: 263 case Expression::kTestValue:
264 // On ARM we have to move the value into a register to do anything 264 // On ARM we have to move the value into a register to do anything
265 // with it. 265 // with it.
266 Move(result_register(), slot); 266 Move(result_register(), slot);
267 Apply(context, result_register()); 267 Apply(context, result_register());
268 break; 268 break;
269 } 269 }
270 } 270 }
271 271
272 272
273 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { 273 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
274 switch (context) { 274 switch (context) {
275 case Expression::kUninitialized: 275 case Expression::kUninitialized:
276 UNREACHABLE(); 276 UNREACHABLE();
277 case Expression::kEffect: 277 case Expression::kEffect:
278 break; 278 break;
279 // Nothing to do. 279 // Nothing to do.
280 case Expression::kValue: 280 case Expression::kValue:
281 case Expression::kTest: 281 case Expression::kTest:
282 case Expression::kValueTest: 282 case Expression::kValueTest:
283 case Expression::kTestValue: 283 case Expression::kTestValue:
284 // On ARM we have to move the value into a register to do anything 284 // On ARM we have to move the value into a register to do anything
285 // with it. 285 // with it.
286 __ mov(result_register(), Operand(lit->handle())); 286 __ mov(result_register(), Operand(lit->handle()));
287 Apply(context, result_register()); 287 Apply(context, result_register());
288 break; 288 break;
289 } 289 }
290 } 290 }
291 291
292 292
293 void FastCodeGenerator::ApplyTOS(Expression::Context context) { 293 void FullCodeGenerator::ApplyTOS(Expression::Context context) {
294 switch (context) { 294 switch (context) {
295 case Expression::kUninitialized: 295 case Expression::kUninitialized:
296 UNREACHABLE(); 296 UNREACHABLE();
297 297
298 case Expression::kEffect: 298 case Expression::kEffect:
299 __ Drop(1); 299 __ Drop(1);
300 break; 300 break;
301 301
302 case Expression::kValue: 302 case Expression::kValue:
303 switch (location_) { 303 switch (location_) {
(...skipping 12 matching lines...) Expand all
316 __ push(ip); 316 __ push(ip);
317 // Fall through. 317 // Fall through.
318 318
319 case Expression::kTest: 319 case Expression::kTest:
320 DoTest(context); 320 DoTest(context);
321 break; 321 break;
322 } 322 }
323 } 323 }
324 324
325 325
326 void FastCodeGenerator::DropAndApply(int count, 326 void FullCodeGenerator::DropAndApply(int count,
327 Expression::Context context, 327 Expression::Context context,
328 Register reg) { 328 Register reg) {
329 ASSERT(count > 0); 329 ASSERT(count > 0);
330 ASSERT(!reg.is(sp)); 330 ASSERT(!reg.is(sp));
331 switch (context) { 331 switch (context) {
332 case Expression::kUninitialized: 332 case Expression::kUninitialized:
333 UNREACHABLE(); 333 UNREACHABLE();
334 334
335 case Expression::kEffect: 335 case Expression::kEffect:
336 __ Drop(count); 336 __ Drop(count);
(...skipping 27 matching lines...) Expand all
364 __ Drop(count - 2); 364 __ Drop(count - 2);
365 __ str(reg, MemOperand(sp, kPointerSize)); 365 __ str(reg, MemOperand(sp, kPointerSize));
366 __ str(reg, MemOperand(sp)); 366 __ str(reg, MemOperand(sp));
367 } 367 }
368 DoTest(context); 368 DoTest(context);
369 break; 369 break;
370 } 370 }
371 } 371 }
372 372
373 373
374 void FastCodeGenerator::Apply(Expression::Context context, 374 void FullCodeGenerator::Apply(Expression::Context context,
375 Label* materialize_true, 375 Label* materialize_true,
376 Label* materialize_false) { 376 Label* materialize_false) {
377 switch (context) { 377 switch (context) {
378 case Expression::kUninitialized: 378 case Expression::kUninitialized:
379 379
380 case Expression::kEffect: 380 case Expression::kEffect:
381 ASSERT_EQ(materialize_true, materialize_false); 381 ASSERT_EQ(materialize_true, materialize_false);
382 __ bind(materialize_true); 382 __ bind(materialize_true);
383 break; 383 break;
384 384
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 case kStack: 425 case kStack:
426 __ push(result_register()); 426 __ push(result_register());
427 break; 427 break;
428 } 428 }
429 __ jmp(false_label_); 429 __ jmp(false_label_);
430 break; 430 break;
431 } 431 }
432 } 432 }
433 433
434 434
435 void FastCodeGenerator::DoTest(Expression::Context context) { 435 void FullCodeGenerator::DoTest(Expression::Context context) {
436 // The value to test is pushed on the stack, and duplicated on the stack 436 // The value to test is pushed on the stack, and duplicated on the stack
437 // if necessary (for value/test and test/value contexts). 437 // if necessary (for value/test and test/value contexts).
438 ASSERT_NE(NULL, true_label_); 438 ASSERT_NE(NULL, true_label_);
439 ASSERT_NE(NULL, false_label_); 439 ASSERT_NE(NULL, false_label_);
440 440
441 // Call the runtime to find the boolean value of the source and then 441 // Call the runtime to find the boolean value of the source and then
442 // translate it into control flow to the pair of labels. 442 // translate it into control flow to the pair of labels.
443 __ CallRuntime(Runtime::kToBool, 1); 443 __ CallRuntime(Runtime::kToBool, 1);
444 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 444 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
445 __ cmp(r0, ip); 445 __ cmp(r0, ip);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 488 }
489 __ bind(&discard); 489 __ bind(&discard);
490 __ Drop(1); 490 __ Drop(1);
491 __ jmp(true_label_); 491 __ jmp(true_label_);
492 break; 492 break;
493 } 493 }
494 } 494 }
495 } 495 }
496 496
497 497
498 MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 498 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
499 switch (slot->type()) { 499 switch (slot->type()) {
500 case Slot::PARAMETER: 500 case Slot::PARAMETER:
501 case Slot::LOCAL: 501 case Slot::LOCAL:
502 return MemOperand(fp, SlotOffset(slot)); 502 return MemOperand(fp, SlotOffset(slot));
503 case Slot::CONTEXT: { 503 case Slot::CONTEXT: {
504 int context_chain_length = 504 int context_chain_length =
505 function_->scope()->ContextChainLength(slot->var()->scope()); 505 function_->scope()->ContextChainLength(slot->var()->scope());
506 __ LoadContext(scratch, context_chain_length); 506 __ LoadContext(scratch, context_chain_length);
507 return CodeGenerator::ContextOperand(scratch, slot->index()); 507 return CodeGenerator::ContextOperand(scratch, slot->index());
508 } 508 }
509 case Slot::LOOKUP: 509 case Slot::LOOKUP:
510 UNREACHABLE(); 510 UNREACHABLE();
511 } 511 }
512 UNREACHABLE(); 512 UNREACHABLE();
513 return MemOperand(r0, 0); 513 return MemOperand(r0, 0);
514 } 514 }
515 515
516 516
517 void FastCodeGenerator::Move(Register destination, Slot* source) { 517 void FullCodeGenerator::Move(Register destination, Slot* source) {
518 // Use destination as scratch. 518 // Use destination as scratch.
519 MemOperand slot_operand = EmitSlotSearch(source, destination); 519 MemOperand slot_operand = EmitSlotSearch(source, destination);
520 __ ldr(destination, slot_operand); 520 __ ldr(destination, slot_operand);
521 } 521 }
522 522
523 523
524 void FastCodeGenerator::Move(Slot* dst, 524 void FullCodeGenerator::Move(Slot* dst,
525 Register src, 525 Register src,
526 Register scratch1, 526 Register scratch1,
527 Register scratch2) { 527 Register scratch2) {
528 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. 528 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
529 ASSERT(!scratch1.is(src) && !scratch2.is(src)); 529 ASSERT(!scratch1.is(src) && !scratch2.is(src));
530 MemOperand location = EmitSlotSearch(dst, scratch1); 530 MemOperand location = EmitSlotSearch(dst, scratch1);
531 __ str(src, location); 531 __ str(src, location);
532 // Emit the write barrier code if the location is in the heap. 532 // Emit the write barrier code if the location is in the heap.
533 if (dst->type() == Slot::CONTEXT) { 533 if (dst->type() == Slot::CONTEXT) {
534 __ mov(scratch2, Operand(Context::SlotOffset(dst->index()))); 534 __ mov(scratch2, Operand(Context::SlotOffset(dst->index())));
535 __ RecordWrite(scratch1, scratch2, src); 535 __ RecordWrite(scratch1, scratch2, src);
536 } 536 }
537 } 537 }
538 538
539 539
540 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { 540 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
541 Comment cmnt(masm_, "[ Declaration"); 541 Comment cmnt(masm_, "[ Declaration");
542 Variable* var = decl->proxy()->var(); 542 Variable* var = decl->proxy()->var();
543 ASSERT(var != NULL); // Must have been resolved. 543 ASSERT(var != NULL); // Must have been resolved.
544 Slot* slot = var->slot(); 544 Slot* slot = var->slot();
545 Property* prop = var->AsProperty(); 545 Property* prop = var->AsProperty();
546 546
547 if (slot != NULL) { 547 if (slot != NULL) {
548 switch (slot->type()) { 548 switch (slot->type()) {
549 case Slot::PARAMETER: 549 case Slot::PARAMETER:
550 case Slot::LOCAL: 550 case Slot::LOCAL:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 __ Call(ic, RelocInfo::CODE_TARGET); 630 __ Call(ic, RelocInfo::CODE_TARGET);
631 631
632 // Value in r0 is ignored (declarations are statements). Receiver 632 // Value in r0 is ignored (declarations are statements). Receiver
633 // and key on stack are discarded. 633 // and key on stack are discarded.
634 __ Drop(2); 634 __ Drop(2);
635 } 635 }
636 } 636 }
637 } 637 }
638 638
639 639
640 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 640 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
641 // Call the runtime to declare the globals. 641 // Call the runtime to declare the globals.
642 // The context is the first argument. 642 // The context is the first argument.
643 __ mov(r1, Operand(pairs)); 643 __ mov(r1, Operand(pairs));
644 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); 644 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0)));
645 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit()); 645 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit());
646 __ CallRuntime(Runtime::kDeclareGlobals, 3); 646 __ CallRuntime(Runtime::kDeclareGlobals, 3);
647 // Return value is ignored. 647 // Return value is ignored.
648 } 648 }
649 649
650 650
651 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 651 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
652 Comment cmnt(masm_, "[ FunctionLiteral"); 652 Comment cmnt(masm_, "[ FunctionLiteral");
653 653
654 // Build the function boilerplate and instantiate it. 654 // Build the function boilerplate and instantiate it.
655 Handle<JSFunction> boilerplate = 655 Handle<JSFunction> boilerplate =
656 Compiler::BuildBoilerplate(expr, script_, this); 656 Compiler::BuildBoilerplate(expr, script_, this);
657 if (HasStackOverflow()) return; 657 if (HasStackOverflow()) return;
658 658
659 ASSERT(boilerplate->IsBoilerplate()); 659 ASSERT(boilerplate->IsBoilerplate());
660 660
661 // Create a new closure. 661 // Create a new closure.
662 __ mov(r0, Operand(boilerplate)); 662 __ mov(r0, Operand(boilerplate));
663 __ stm(db_w, sp, cp.bit() | r0.bit()); 663 __ stm(db_w, sp, cp.bit() | r0.bit());
664 __ CallRuntime(Runtime::kNewClosure, 2); 664 __ CallRuntime(Runtime::kNewClosure, 2);
665 Apply(context_, r0); 665 Apply(context_, r0);
666 } 666 }
667 667
668 668
669 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 669 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
670 Comment cmnt(masm_, "[ VariableProxy"); 670 Comment cmnt(masm_, "[ VariableProxy");
671 EmitVariableLoad(expr->var(), context_); 671 EmitVariableLoad(expr->var(), context_);
672 } 672 }
673 673
674 674
675 void FastCodeGenerator::EmitVariableLoad(Variable* var, 675 void FullCodeGenerator::EmitVariableLoad(Variable* var,
676 Expression::Context context) { 676 Expression::Context context) {
677 Expression* rewrite = var->rewrite(); 677 Expression* rewrite = var->rewrite();
678 if (rewrite == NULL) { 678 if (rewrite == NULL) {
679 ASSERT(var->is_global()); 679 ASSERT(var->is_global());
680 Comment cmnt(masm_, "Global variable"); 680 Comment cmnt(masm_, "Global variable");
681 // Use inline caching. Variable name is passed in r2 and the global 681 // Use inline caching. Variable name is passed in r2 and the global
682 // object on the stack. 682 // object on the stack.
683 __ ldr(ip, CodeGenerator::GlobalObject()); 683 __ ldr(ip, CodeGenerator::GlobalObject());
684 __ push(ip); 684 __ push(ip);
685 __ mov(r2, Operand(var->name())); 685 __ mov(r2, Operand(var->name()));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 // Do a keyed property load. 738 // Do a keyed property load.
739 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 739 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
740 __ Call(ic, RelocInfo::CODE_TARGET); 740 __ Call(ic, RelocInfo::CODE_TARGET);
741 741
742 // Drop key and object left on the stack by IC, and push the result. 742 // Drop key and object left on the stack by IC, and push the result.
743 DropAndApply(2, context, r0); 743 DropAndApply(2, context, r0);
744 } 744 }
745 } 745 }
746 746
747 747
748 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 748 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
749 Comment cmnt(masm_, "[ RegExpLiteral"); 749 Comment cmnt(masm_, "[ RegExpLiteral");
750 Label done; 750 Label done;
751 // Registers will be used as follows: 751 // Registers will be used as follows:
752 // r4 = JS function, literals array 752 // r4 = JS function, literals array
753 // r3 = literal index 753 // r3 = literal index
754 // r2 = RegExp pattern 754 // r2 = RegExp pattern
755 // r1 = RegExp flags 755 // r1 = RegExp flags
756 // r0 = temp + return value (RegExp literal) 756 // r0 = temp + return value (RegExp literal)
757 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 757 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
758 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); 758 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
759 int literal_offset = 759 int literal_offset =
760 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 760 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
761 __ ldr(r0, FieldMemOperand(r4, literal_offset)); 761 __ ldr(r0, FieldMemOperand(r4, literal_offset));
762 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 762 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
763 __ cmp(r0, ip); 763 __ cmp(r0, ip);
764 __ b(ne, &done); 764 __ b(ne, &done);
765 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); 765 __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
766 __ mov(r2, Operand(expr->pattern())); 766 __ mov(r2, Operand(expr->pattern()));
767 __ mov(r1, Operand(expr->flags())); 767 __ mov(r1, Operand(expr->flags()));
768 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); 768 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
769 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 769 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
770 __ bind(&done); 770 __ bind(&done);
771 Apply(context_, r0); 771 Apply(context_, r0);
772 } 772 }
773 773
774 774
775 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 775 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
776 Comment cmnt(masm_, "[ ObjectLiteral"); 776 Comment cmnt(masm_, "[ ObjectLiteral");
777 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 777 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
778 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); 778 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
779 __ mov(r1, Operand(Smi::FromInt(expr->literal_index()))); 779 __ mov(r1, Operand(Smi::FromInt(expr->literal_index())));
780 __ mov(r0, Operand(expr->constant_properties())); 780 __ mov(r0, Operand(expr->constant_properties()));
781 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit()); 781 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit());
782 if (expr->depth() > 1) { 782 if (expr->depth() > 1) {
783 __ CallRuntime(Runtime::kCreateObjectLiteral, 3); 783 __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
784 } else { 784 } else {
785 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3); 785 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 } 840 }
841 841
842 if (result_saved) { 842 if (result_saved) {
843 ApplyTOS(context_); 843 ApplyTOS(context_);
844 } else { 844 } else {
845 Apply(context_, r0); 845 Apply(context_, r0);
846 } 846 }
847 } 847 }
848 848
849 849
850 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 850 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
851 Comment cmnt(masm_, "[ ArrayLiteral"); 851 Comment cmnt(masm_, "[ ArrayLiteral");
852 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 852 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
853 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); 853 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
854 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); 854 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
855 __ mov(r1, Operand(expr->constant_elements())); 855 __ mov(r1, Operand(expr->constant_elements()));
856 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit()); 856 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit());
857 if (expr->depth() > 1) { 857 if (expr->depth() > 1) {
858 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 858 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
859 } else { 859 } else {
860 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 860 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 } 893 }
894 894
895 if (result_saved) { 895 if (result_saved) {
896 ApplyTOS(context_); 896 ApplyTOS(context_);
897 } else { 897 } else {
898 Apply(context_, r0); 898 Apply(context_, r0);
899 } 899 }
900 } 900 }
901 901
902 902
903 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 903 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
904 SetSourcePosition(prop->position()); 904 SetSourcePosition(prop->position());
905 Literal* key = prop->key()->AsLiteral(); 905 Literal* key = prop->key()->AsLiteral();
906 __ mov(r2, Operand(key->handle())); 906 __ mov(r2, Operand(key->handle()));
907 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 907 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
908 __ Call(ic, RelocInfo::CODE_TARGET); 908 __ Call(ic, RelocInfo::CODE_TARGET);
909 } 909 }
910 910
911 911
912 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 912 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
913 SetSourcePosition(prop->position()); 913 SetSourcePosition(prop->position());
914 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 914 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
915 __ Call(ic, RelocInfo::CODE_TARGET); 915 __ Call(ic, RelocInfo::CODE_TARGET);
916 } 916 }
917 917
918 918
919 void FastCodeGenerator::EmitBinaryOp(Token::Value op, 919 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
920 Expression::Context context) { 920 Expression::Context context) {
921 __ pop(r1); 921 __ pop(r1);
922 GenericBinaryOpStub stub(op, NO_OVERWRITE); 922 GenericBinaryOpStub stub(op, NO_OVERWRITE);
923 __ CallStub(&stub); 923 __ CallStub(&stub);
924 Apply(context, r0); 924 Apply(context, r0);
925 } 925 }
926 926
927 927
928 void FastCodeGenerator::EmitVariableAssignment(Variable* var, 928 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
929 Expression::Context context) { 929 Expression::Context context) {
930 ASSERT(var != NULL); 930 ASSERT(var != NULL);
931 ASSERT(var->is_global() || var->slot() != NULL); 931 ASSERT(var->is_global() || var->slot() != NULL);
932 if (var->is_global()) { 932 if (var->is_global()) {
933 // Assignment to a global variable. Use inline caching for the 933 // Assignment to a global variable. Use inline caching for the
934 // assignment. Right-hand-side value is passed in r0, variable name in 934 // assignment. Right-hand-side value is passed in r0, variable name in
935 // r2, and the global object on the stack. 935 // r2, and the global object on the stack.
936 __ mov(r2, Operand(var->name())); 936 __ mov(r2, Operand(var->name()));
937 __ ldr(ip, CodeGenerator::GlobalObject()); 937 __ ldr(ip, CodeGenerator::GlobalObject());
938 __ push(ip); 938 __ push(ip);
(...skipping 29 matching lines...) Expand all
968 } 968 }
969 Apply(context, result_register()); 969 Apply(context, result_register());
970 } else { 970 } else {
971 // Variables rewritten as properties are not treated as variables in 971 // Variables rewritten as properties are not treated as variables in
972 // assignments. 972 // assignments.
973 UNREACHABLE(); 973 UNREACHABLE();
974 } 974 }
975 } 975 }
976 976
977 977
978 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 978 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
979 // Assignment to a property, using a named store IC. 979 // Assignment to a property, using a named store IC.
980 Property* prop = expr->target()->AsProperty(); 980 Property* prop = expr->target()->AsProperty();
981 ASSERT(prop != NULL); 981 ASSERT(prop != NULL);
982 ASSERT(prop->key()->AsLiteral() != NULL); 982 ASSERT(prop->key()->AsLiteral() != NULL);
983 983
984 // If the assignment starts a block of assignments to the same object, 984 // If the assignment starts a block of assignments to the same object,
985 // change to slow case to avoid the quadratic behavior of repeatedly 985 // change to slow case to avoid the quadratic behavior of repeatedly
986 // adding fast properties. 986 // adding fast properties.
987 if (expr->starts_initialization_block()) { 987 if (expr->starts_initialization_block()) {
988 __ push(result_register()); 988 __ push(result_register());
(...skipping 15 matching lines...) Expand all
1004 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. 1004 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value.
1005 __ push(ip); 1005 __ push(ip);
1006 __ CallRuntime(Runtime::kToFastProperties, 1); 1006 __ CallRuntime(Runtime::kToFastProperties, 1);
1007 __ pop(r0); 1007 __ pop(r0);
1008 } 1008 }
1009 1009
1010 DropAndApply(1, context_, r0); 1010 DropAndApply(1, context_, r0);
1011 } 1011 }
1012 1012
1013 1013
1014 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1014 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1015 // Assignment to a property, using a keyed store IC. 1015 // Assignment to a property, using a keyed store IC.
1016 1016
1017 // If the assignment starts a block of assignments to the same object, 1017 // If the assignment starts a block of assignments to the same object,
1018 // change to slow case to avoid the quadratic behavior of repeatedly 1018 // change to slow case to avoid the quadratic behavior of repeatedly
1019 // adding fast properties. 1019 // adding fast properties.
1020 if (expr->starts_initialization_block()) { 1020 if (expr->starts_initialization_block()) {
1021 __ push(result_register()); 1021 __ push(result_register());
1022 // Receiver is now under the key and value. 1022 // Receiver is now under the key and value.
1023 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); 1023 __ ldr(ip, MemOperand(sp, 2 * kPointerSize));
1024 __ push(ip); 1024 __ push(ip);
(...skipping 14 matching lines...) Expand all
1039 __ push(ip); 1039 __ push(ip);
1040 __ CallRuntime(Runtime::kToFastProperties, 1); 1040 __ CallRuntime(Runtime::kToFastProperties, 1);
1041 __ pop(r0); 1041 __ pop(r0);
1042 } 1042 }
1043 1043
1044 // Receiver and key are still on stack. 1044 // Receiver and key are still on stack.
1045 DropAndApply(2, context_, r0); 1045 DropAndApply(2, context_, r0);
1046 } 1046 }
1047 1047
1048 1048
1049 void FastCodeGenerator::VisitProperty(Property* expr) { 1049 void FullCodeGenerator::VisitProperty(Property* expr) {
1050 Comment cmnt(masm_, "[ Property"); 1050 Comment cmnt(masm_, "[ Property");
1051 Expression* key = expr->key(); 1051 Expression* key = expr->key();
1052 1052
1053 // Evaluate receiver. 1053 // Evaluate receiver.
1054 VisitForValue(expr->obj(), kStack); 1054 VisitForValue(expr->obj(), kStack);
1055 1055
1056 if (key->IsPropertyName()) { 1056 if (key->IsPropertyName()) {
1057 EmitNamedPropertyLoad(expr); 1057 EmitNamedPropertyLoad(expr);
1058 // Drop receiver left on the stack by IC. 1058 // Drop receiver left on the stack by IC.
1059 DropAndApply(1, context_, r0); 1059 DropAndApply(1, context_, r0);
1060 } else { 1060 } else {
1061 VisitForValue(expr->key(), kStack); 1061 VisitForValue(expr->key(), kStack);
1062 EmitKeyedPropertyLoad(expr); 1062 EmitKeyedPropertyLoad(expr);
1063 // Drop key and receiver left on the stack by IC. 1063 // Drop key and receiver left on the stack by IC.
1064 DropAndApply(2, context_, r0); 1064 DropAndApply(2, context_, r0);
1065 } 1065 }
1066 } 1066 }
1067 1067
1068 void FastCodeGenerator::EmitCallWithIC(Call* expr, 1068 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1069 Handle<Object> ignored, 1069 Handle<Object> ignored,
1070 RelocInfo::Mode mode) { 1070 RelocInfo::Mode mode) {
1071 // Code common for calls using the IC. 1071 // Code common for calls using the IC.
1072 ZoneList<Expression*>* args = expr->arguments(); 1072 ZoneList<Expression*>* args = expr->arguments();
1073 int arg_count = args->length(); 1073 int arg_count = args->length();
1074 for (int i = 0; i < arg_count; i++) { 1074 for (int i = 0; i < arg_count; i++) {
1075 VisitForValue(args->at(i), kStack); 1075 VisitForValue(args->at(i), kStack);
1076 } 1076 }
1077 // Record source position for debugger. 1077 // Record source position for debugger.
1078 SetSourcePosition(expr->position()); 1078 SetSourcePosition(expr->position());
1079 // Call the IC initialization code. 1079 // Call the IC initialization code.
1080 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1080 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1081 NOT_IN_LOOP); 1081 NOT_IN_LOOP);
1082 __ Call(ic, mode); 1082 __ Call(ic, mode);
1083 // Restore context register. 1083 // Restore context register.
1084 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1084 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1085 // Discard the function left on TOS. 1085 // Discard the function left on TOS.
1086 DropAndApply(1, context_, r0); 1086 DropAndApply(1, context_, r0);
1087 } 1087 }
1088 1088
1089 1089
1090 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1090 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1091 // Code common for calls using the call stub. 1091 // Code common for calls using the call stub.
1092 ZoneList<Expression*>* args = expr->arguments(); 1092 ZoneList<Expression*>* args = expr->arguments();
1093 int arg_count = args->length(); 1093 int arg_count = args->length();
1094 for (int i = 0; i < arg_count; i++) { 1094 for (int i = 0; i < arg_count; i++) {
1095 VisitForValue(args->at(i), kStack); 1095 VisitForValue(args->at(i), kStack);
1096 } 1096 }
1097 // Record source position for debugger. 1097 // Record source position for debugger.
1098 SetSourcePosition(expr->position()); 1098 SetSourcePosition(expr->position());
1099 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); 1099 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
1100 __ CallStub(&stub); 1100 __ CallStub(&stub);
1101 // Restore context register. 1101 // Restore context register.
1102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1103 // Discard the function left on TOS. 1103 // Discard the function left on TOS.
1104 DropAndApply(1, context_, r0); 1104 DropAndApply(1, context_, r0);
1105 } 1105 }
1106 1106
1107 1107
1108 void FastCodeGenerator::VisitCall(Call* expr) { 1108 void FullCodeGenerator::VisitCall(Call* expr) {
1109 Comment cmnt(masm_, "[ Call"); 1109 Comment cmnt(masm_, "[ Call");
1110 Expression* fun = expr->expression(); 1110 Expression* fun = expr->expression();
1111 Variable* var = fun->AsVariableProxy()->AsVariable(); 1111 Variable* var = fun->AsVariableProxy()->AsVariable();
1112 1112
1113 if (var != NULL && var->is_possibly_eval()) { 1113 if (var != NULL && var->is_possibly_eval()) {
1114 // Call to the identifier 'eval'. 1114 // Call to the identifier 'eval'.
1115 UNREACHABLE(); 1115 UNREACHABLE();
1116 } else if (var != NULL && !var->is_this() && var->is_global()) { 1116 } else if (var != NULL && !var->is_this() && var->is_global()) {
1117 // Call to a global variable. 1117 // Call to a global variable.
1118 __ mov(r1, Operand(var->name())); 1118 __ mov(r1, Operand(var->name()));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 // Load global receiver object. 1169 // Load global receiver object.
1170 __ ldr(r1, CodeGenerator::GlobalObject()); 1170 __ ldr(r1, CodeGenerator::GlobalObject());
1171 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 1171 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
1172 __ push(r1); 1172 __ push(r1);
1173 // Emit function call. 1173 // Emit function call.
1174 EmitCallWithStub(expr); 1174 EmitCallWithStub(expr);
1175 } 1175 }
1176 } 1176 }
1177 1177
1178 1178
1179 void FastCodeGenerator::VisitCallNew(CallNew* expr) { 1179 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
1180 Comment cmnt(masm_, "[ CallNew"); 1180 Comment cmnt(masm_, "[ CallNew");
1181 // According to ECMA-262, section 11.2.2, page 44, the function 1181 // According to ECMA-262, section 11.2.2, page 44, the function
1182 // expression in new calls must be evaluated before the 1182 // expression in new calls must be evaluated before the
1183 // arguments. 1183 // arguments.
1184 // Push function on the stack. 1184 // Push function on the stack.
1185 VisitForValue(expr->expression(), kStack); 1185 VisitForValue(expr->expression(), kStack);
1186 1186
1187 // Push global object (receiver). 1187 // Push global object (receiver).
1188 __ ldr(r0, CodeGenerator::GlobalObject()); 1188 __ ldr(r0, CodeGenerator::GlobalObject());
1189 __ push(r0); 1189 __ push(r0);
(...skipping 14 matching lines...) Expand all
1204 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 1204 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
1205 1205
1206 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1206 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1207 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1207 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1208 1208
1209 // Replace function on TOS with result in r0, or pop it. 1209 // Replace function on TOS with result in r0, or pop it.
1210 DropAndApply(1, context_, r0); 1210 DropAndApply(1, context_, r0);
1211 } 1211 }
1212 1212
1213 1213
1214 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1214 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1215 Comment cmnt(masm_, "[ CallRuntime"); 1215 Comment cmnt(masm_, "[ CallRuntime");
1216 ZoneList<Expression*>* args = expr->arguments(); 1216 ZoneList<Expression*>* args = expr->arguments();
1217 1217
1218 if (expr->is_jsruntime()) { 1218 if (expr->is_jsruntime()) {
1219 // Prepare for calling JS runtime function. 1219 // Prepare for calling JS runtime function.
1220 __ mov(r1, Operand(expr->name())); 1220 __ mov(r1, Operand(expr->name()));
1221 __ ldr(r0, CodeGenerator::GlobalObject()); 1221 __ ldr(r0, CodeGenerator::GlobalObject());
1222 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); 1222 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
1223 __ stm(db_w, sp, r1.bit() | r0.bit()); 1223 __ stm(db_w, sp, r1.bit() | r0.bit());
1224 } 1224 }
(...skipping 14 matching lines...) Expand all
1239 // Discard the function left on TOS. 1239 // Discard the function left on TOS.
1240 DropAndApply(1, context_, r0); 1240 DropAndApply(1, context_, r0);
1241 } else { 1241 } else {
1242 // Call the C runtime function. 1242 // Call the C runtime function.
1243 __ CallRuntime(expr->function(), arg_count); 1243 __ CallRuntime(expr->function(), arg_count);
1244 Apply(context_, r0); 1244 Apply(context_, r0);
1245 } 1245 }
1246 } 1246 }
1247 1247
1248 1248
1249 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 1249 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1250 switch (expr->op()) { 1250 switch (expr->op()) {
1251 case Token::VOID: { 1251 case Token::VOID: {
1252 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 1252 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1253 VisitForEffect(expr->expression()); 1253 VisitForEffect(expr->expression());
1254 switch (context_) { 1254 switch (context_) {
1255 case Expression::kUninitialized: 1255 case Expression::kUninitialized:
1256 UNREACHABLE(); 1256 UNREACHABLE();
1257 break; 1257 break;
1258 case Expression::kEffect: 1258 case Expression::kEffect:
1259 break; 1259 break;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 Apply(context_, r0); 1350 Apply(context_, r0);
1351 break; 1351 break;
1352 } 1352 }
1353 1353
1354 default: 1354 default:
1355 UNREACHABLE(); 1355 UNREACHABLE();
1356 } 1356 }
1357 } 1357 }
1358 1358
1359 1359
1360 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 1360 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1361 Comment cmnt(masm_, "[ CountOperation"); 1361 Comment cmnt(masm_, "[ CountOperation");
1362 1362
1363 // Expression can only be a property, a global or a (parameter or local) 1363 // Expression can only be a property, a global or a (parameter or local)
1364 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1364 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
1365 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1365 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1366 LhsKind assign_type = VARIABLE; 1366 LhsKind assign_type = VARIABLE;
1367 Property* prop = expr->expression()->AsProperty(); 1367 Property* prop = expr->expression()->AsProperty();
1368 // In case of a property we use the uninitialized expression context 1368 // In case of a property we use the uninitialized expression context
1369 // of the key to detect a named property. 1369 // of the key to detect a named property.
1370 if (prop != NULL) { 1370 if (prop != NULL) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 } 1476 }
1477 } else { 1477 } else {
1478 DropAndApply(2, context_, r0); 1478 DropAndApply(2, context_, r0);
1479 } 1479 }
1480 break; 1480 break;
1481 } 1481 }
1482 } 1482 }
1483 } 1483 }
1484 1484
1485 1485
1486 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 1486 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
1487 Comment cmnt(masm_, "[ BinaryOperation"); 1487 Comment cmnt(masm_, "[ BinaryOperation");
1488 switch (expr->op()) { 1488 switch (expr->op()) {
1489 case Token::COMMA: 1489 case Token::COMMA:
1490 VisitForEffect(expr->left()); 1490 VisitForEffect(expr->left());
1491 Visit(expr->right()); 1491 Visit(expr->right());
1492 break; 1492 break;
1493 1493
1494 case Token::OR: 1494 case Token::OR:
1495 case Token::AND: 1495 case Token::AND:
1496 EmitLogicalOperation(expr); 1496 EmitLogicalOperation(expr);
(...skipping 14 matching lines...) Expand all
1511 VisitForValue(expr->right(), kAccumulator); 1511 VisitForValue(expr->right(), kAccumulator);
1512 EmitBinaryOp(expr->op(), context_); 1512 EmitBinaryOp(expr->op(), context_);
1513 break; 1513 break;
1514 1514
1515 default: 1515 default:
1516 UNREACHABLE(); 1516 UNREACHABLE();
1517 } 1517 }
1518 } 1518 }
1519 1519
1520 1520
1521 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1521 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1522 Comment cmnt(masm_, "[ CompareOperation"); 1522 Comment cmnt(masm_, "[ CompareOperation");
1523 1523
1524 // Always perform the comparison for its control flow. Pack the result 1524 // Always perform the comparison for its control flow. Pack the result
1525 // into the expression's context after the comparison is performed. 1525 // into the expression's context after the comparison is performed.
1526 Label materialize_true, materialize_false, done; 1526 Label materialize_true, materialize_false, done;
1527 // Initially assume we are in a test context. 1527 // Initially assume we are in a test context.
1528 Label* if_true = true_label_; 1528 Label* if_true = true_label_;
1529 Label* if_false = false_label_; 1529 Label* if_false = false_label_;
1530 switch (context_) { 1530 switch (context_) {
1531 case Expression::kUninitialized: 1531 case Expression::kUninitialized:
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 __ jmp(if_false); 1626 __ jmp(if_false);
1627 } 1627 }
1628 } 1628 }
1629 1629
1630 // Convert the result of the comparison into one expected for this 1630 // Convert the result of the comparison into one expected for this
1631 // expression's context. 1631 // expression's context.
1632 Apply(context_, if_true, if_false); 1632 Apply(context_, if_true, if_false);
1633 } 1633 }
1634 1634
1635 1635
1636 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1636 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1637 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1637 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1638 Apply(context_, r0); 1638 Apply(context_, r0);
1639 } 1639 }
1640 1640
1641 1641
1642 Register FastCodeGenerator::result_register() { return r0; } 1642 Register FullCodeGenerator::result_register() { return r0; }
1643 1643
1644 1644
1645 Register FastCodeGenerator::context_register() { return cp; } 1645 Register FullCodeGenerator::context_register() { return cp; }
1646 1646
1647 1647
1648 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 1648 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
1649 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 1649 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
1650 __ str(value, MemOperand(fp, frame_offset)); 1650 __ str(value, MemOperand(fp, frame_offset));
1651 } 1651 }
1652 1652
1653 1653
1654 void FastCodeGenerator::LoadContextField(Register dst, int context_index) { 1654 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
1655 __ ldr(dst, CodeGenerator::ContextOperand(cp, context_index)); 1655 __ ldr(dst, CodeGenerator::ContextOperand(cp, context_index));
1656 } 1656 }
1657 1657
1658 1658
1659 // ---------------------------------------------------------------------------- 1659 // ----------------------------------------------------------------------------
1660 // Non-local control flow support. 1660 // Non-local control flow support.
1661 1661
1662 void FastCodeGenerator::EnterFinallyBlock() { 1662 void FullCodeGenerator::EnterFinallyBlock() {
1663 ASSERT(!result_register().is(r1)); 1663 ASSERT(!result_register().is(r1));
1664 // Store result register while executing finally block. 1664 // Store result register while executing finally block.
1665 __ push(result_register()); 1665 __ push(result_register());
1666 // Cook return address in link register to stack (smi encoded Code* delta) 1666 // Cook return address in link register to stack (smi encoded Code* delta)
1667 __ sub(r1, lr, Operand(masm_->CodeObject())); 1667 __ sub(r1, lr, Operand(masm_->CodeObject()));
1668 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 1668 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
1669 ASSERT_EQ(0, kSmiTag); 1669 ASSERT_EQ(0, kSmiTag);
1670 __ add(r1, r1, Operand(r1)); // Convert to smi. 1670 __ add(r1, r1, Operand(r1)); // Convert to smi.
1671 __ push(r1); 1671 __ push(r1);
1672 } 1672 }
1673 1673
1674 1674
1675 void FastCodeGenerator::ExitFinallyBlock() { 1675 void FullCodeGenerator::ExitFinallyBlock() {
1676 ASSERT(!result_register().is(r1)); 1676 ASSERT(!result_register().is(r1));
1677 // Restore result register from stack. 1677 // Restore result register from stack.
1678 __ pop(r1); 1678 __ pop(r1);
1679 // Uncook return address and return. 1679 // Uncook return address and return.
1680 __ pop(result_register()); 1680 __ pop(result_register());
1681 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 1681 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
1682 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 1682 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
1683 __ add(pc, r1, Operand(masm_->CodeObject())); 1683 __ add(pc, r1, Operand(masm_->CodeObject()));
1684 } 1684 }
1685 1685
1686 1686
1687 #undef __ 1687 #undef __
1688 1688
1689 } } // namespace v8::internal 1689 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698