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

Side by Side Diff: src/mips/full-codegen-mips.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 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/mips/disasm-mips.cc ('k') | src/mips/ic-mips.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 // Note on Mips implementation: 9 // Note on Mips implementation:
10 // 10 //
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // never be emitted by normal code. 43 // never be emitted by normal code.
44 class JumpPatchSite BASE_EMBEDDED { 44 class JumpPatchSite BASE_EMBEDDED {
45 public: 45 public:
46 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 46 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
47 #ifdef DEBUG 47 #ifdef DEBUG
48 info_emitted_ = false; 48 info_emitted_ = false;
49 #endif 49 #endif
50 } 50 }
51 51
52 ~JumpPatchSite() { 52 ~JumpPatchSite() {
53 ASSERT(patch_site_.is_bound() == info_emitted_); 53 DCHECK(patch_site_.is_bound() == info_emitted_);
54 } 54 }
55 55
56 // When initially emitting this ensure that a jump is always generated to skip 56 // When initially emitting this ensure that a jump is always generated to skip
57 // the inlined smi code. 57 // the inlined smi code.
58 void EmitJumpIfNotSmi(Register reg, Label* target) { 58 void EmitJumpIfNotSmi(Register reg, Label* target) {
59 ASSERT(!patch_site_.is_bound() && !info_emitted_); 59 DCHECK(!patch_site_.is_bound() && !info_emitted_);
60 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 60 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
61 __ bind(&patch_site_); 61 __ bind(&patch_site_);
62 __ andi(at, reg, 0); 62 __ andi(at, reg, 0);
63 // Always taken before patched. 63 // Always taken before patched.
64 __ BranchShort(target, eq, at, Operand(zero_reg)); 64 __ BranchShort(target, eq, at, Operand(zero_reg));
65 } 65 }
66 66
67 // When initially emitting this ensure that a jump is never generated to skip 67 // When initially emitting this ensure that a jump is never generated to skip
68 // the inlined smi code. 68 // the inlined smi code.
69 void EmitJumpIfSmi(Register reg, Label* target) { 69 void EmitJumpIfSmi(Register reg, Label* target) {
70 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 70 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
71 ASSERT(!patch_site_.is_bound() && !info_emitted_); 71 DCHECK(!patch_site_.is_bound() && !info_emitted_);
72 __ bind(&patch_site_); 72 __ bind(&patch_site_);
73 __ andi(at, reg, 0); 73 __ andi(at, reg, 0);
74 // Never taken before patched. 74 // Never taken before patched.
75 __ BranchShort(target, ne, at, Operand(zero_reg)); 75 __ BranchShort(target, ne, at, Operand(zero_reg));
76 } 76 }
77 77
78 void EmitPatchInfo() { 78 void EmitPatchInfo() {
79 if (patch_site_.is_bound()) { 79 if (patch_site_.is_bound()) {
80 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_); 80 int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
81 Register reg = Register::from_code(delta_to_patch_site / kImm16Mask); 81 Register reg = Register::from_code(delta_to_patch_site / kImm16Mask);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // the frame (that is done below). 153 // the frame (that is done below).
154 FrameScope frame_scope(masm_, StackFrame::MANUAL); 154 FrameScope frame_scope(masm_, StackFrame::MANUAL);
155 155
156 info->set_prologue_offset(masm_->pc_offset()); 156 info->set_prologue_offset(masm_->pc_offset());
157 __ Prologue(info->IsCodePreAgingActive()); 157 __ Prologue(info->IsCodePreAgingActive());
158 info->AddNoFrameRange(0, masm_->pc_offset()); 158 info->AddNoFrameRange(0, masm_->pc_offset());
159 159
160 { Comment cmnt(masm_, "[ Allocate locals"); 160 { Comment cmnt(masm_, "[ Allocate locals");
161 int locals_count = info->scope()->num_stack_slots(); 161 int locals_count = info->scope()->num_stack_slots();
162 // Generators allocate locals, if any, in context slots. 162 // Generators allocate locals, if any, in context slots.
163 ASSERT(!info->function()->is_generator() || locals_count == 0); 163 DCHECK(!info->function()->is_generator() || locals_count == 0);
164 if (locals_count > 0) { 164 if (locals_count > 0) {
165 if (locals_count >= 128) { 165 if (locals_count >= 128) {
166 Label ok; 166 Label ok;
167 __ Subu(t5, sp, Operand(locals_count * kPointerSize)); 167 __ Subu(t5, sp, Operand(locals_count * kPointerSize));
168 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 168 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
169 __ Branch(&ok, hs, t5, Operand(a2)); 169 __ Branch(&ok, hs, t5, Operand(a2));
170 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); 170 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
171 __ bind(&ok); 171 __ bind(&ok);
172 } 172 }
173 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); 173 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 Comment cmnt(masm_, "[ Declarations"); 294 Comment cmnt(masm_, "[ Declarations");
295 scope()->VisitIllegalRedeclaration(this); 295 scope()->VisitIllegalRedeclaration(this);
296 296
297 } else { 297 } else {
298 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 298 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
299 { Comment cmnt(masm_, "[ Declarations"); 299 { Comment cmnt(masm_, "[ Declarations");
300 // For named function expressions, declare the function name as a 300 // For named function expressions, declare the function name as a
301 // constant. 301 // constant.
302 if (scope()->is_function_scope() && scope()->function() != NULL) { 302 if (scope()->is_function_scope() && scope()->function() != NULL) {
303 VariableDeclaration* function = scope()->function(); 303 VariableDeclaration* function = scope()->function();
304 ASSERT(function->proxy()->var()->mode() == CONST || 304 DCHECK(function->proxy()->var()->mode() == CONST ||
305 function->proxy()->var()->mode() == CONST_LEGACY); 305 function->proxy()->var()->mode() == CONST_LEGACY);
306 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 306 DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED);
307 VisitVariableDeclaration(function); 307 VisitVariableDeclaration(function);
308 } 308 }
309 VisitDeclarations(scope()->declarations()); 309 VisitDeclarations(scope()->declarations());
310 } 310 }
311 311
312 { Comment cmnt(masm_, "[ Stack check"); 312 { Comment cmnt(masm_, "[ Stack check");
313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
314 Label ok; 314 Label ok;
315 __ LoadRoot(at, Heap::kStackLimitRootIndex); 315 __ LoadRoot(at, Heap::kStackLimitRootIndex);
316 __ Branch(&ok, hs, sp, Operand(at)); 316 __ Branch(&ok, hs, sp, Operand(at));
317 Handle<Code> stack_check = isolate()->builtins()->StackCheck(); 317 Handle<Code> stack_check = isolate()->builtins()->StackCheck();
318 PredictableCodeSizeScope predictable(masm_, 318 PredictableCodeSizeScope predictable(masm_,
319 masm_->CallSize(stack_check, RelocInfo::CODE_TARGET)); 319 masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
320 __ Call(stack_check, RelocInfo::CODE_TARGET); 320 __ Call(stack_check, RelocInfo::CODE_TARGET);
321 __ bind(&ok); 321 __ bind(&ok);
322 } 322 }
323 323
324 { Comment cmnt(masm_, "[ Body"); 324 { Comment cmnt(masm_, "[ Body");
325 ASSERT(loop_depth() == 0); 325 DCHECK(loop_depth() == 0);
326 VisitStatements(function()->body()); 326 VisitStatements(function()->body());
327 ASSERT(loop_depth() == 0); 327 DCHECK(loop_depth() == 0);
328 } 328 }
329 } 329 }
330 330
331 // Always emit a 'return undefined' in case control fell off the end of 331 // Always emit a 'return undefined' in case control fell off the end of
332 // the body. 332 // the body.
333 { Comment cmnt(masm_, "[ return <undefined>;"); 333 { Comment cmnt(masm_, "[ return <undefined>;");
334 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 334 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
335 } 335 }
336 EmitReturnSequence(); 336 EmitReturnSequence();
337 } 337 }
338 338
339 339
340 void FullCodeGenerator::ClearAccumulator() { 340 void FullCodeGenerator::ClearAccumulator() {
341 ASSERT(Smi::FromInt(0) == 0); 341 DCHECK(Smi::FromInt(0) == 0);
342 __ mov(v0, zero_reg); 342 __ mov(v0, zero_reg);
343 } 343 }
344 344
345 345
346 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 346 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
347 __ li(a2, Operand(profiling_counter_)); 347 __ li(a2, Operand(profiling_counter_));
348 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); 348 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
349 __ Subu(a3, a3, Operand(Smi::FromInt(delta))); 349 __ Subu(a3, a3, Operand(Smi::FromInt(delta)));
350 __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset)); 350 __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
351 } 351 }
(...skipping 14 matching lines...) Expand all
366 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 366 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
367 Label* back_edge_target) { 367 Label* back_edge_target) {
368 // The generated code is used in Deoptimizer::PatchStackCheckCodeAt so we need 368 // The generated code is used in Deoptimizer::PatchStackCheckCodeAt so we need
369 // to make sure it is constant. Branch may emit a skip-or-jump sequence 369 // to make sure it is constant. Branch may emit a skip-or-jump sequence
370 // instead of the normal Branch. It seems that the "skip" part of that 370 // instead of the normal Branch. It seems that the "skip" part of that
371 // sequence is about as long as this Branch would be so it is safe to ignore 371 // sequence is about as long as this Branch would be so it is safe to ignore
372 // that. 372 // that.
373 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 373 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
374 Comment cmnt(masm_, "[ Back edge bookkeeping"); 374 Comment cmnt(masm_, "[ Back edge bookkeeping");
375 Label ok; 375 Label ok;
376 ASSERT(back_edge_target->is_bound()); 376 DCHECK(back_edge_target->is_bound());
377 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 377 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
378 int weight = Min(kMaxBackEdgeWeight, 378 int weight = Min(kMaxBackEdgeWeight,
379 Max(1, distance / kCodeSizeMultiplier)); 379 Max(1, distance / kCodeSizeMultiplier));
380 EmitProfilingCounterDecrement(weight); 380 EmitProfilingCounterDecrement(weight);
381 __ slt(at, a3, zero_reg); 381 __ slt(at, a3, zero_reg);
382 __ beq(at, zero_reg, &ok); 382 __ beq(at, zero_reg, &ok);
383 // Call will emit a li t9 first, so it is safe to use the delay slot. 383 // Call will emit a li t9 first, so it is safe to use the delay slot.
384 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 384 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
385 // Record a mapping of this PC offset to the OSR id. This is used to find 385 // Record a mapping of this PC offset to the OSR id. This is used to find
386 // the AST id from the unoptimized code in order to use it as a key into 386 // the AST id from the unoptimized code in order to use it as a key into
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 int no_frame_start = masm_->pc_offset(); 445 int no_frame_start = masm_->pc_offset();
446 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); 446 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit()));
447 masm_->Addu(sp, sp, Operand(sp_delta)); 447 masm_->Addu(sp, sp, Operand(sp_delta));
448 masm_->Jump(ra); 448 masm_->Jump(ra);
449 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 449 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
450 } 450 }
451 451
452 #ifdef DEBUG 452 #ifdef DEBUG
453 // Check that the size of the code used for returning is large enough 453 // Check that the size of the code used for returning is large enough
454 // for the debugger's requirements. 454 // for the debugger's requirements.
455 ASSERT(Assembler::kJSReturnSequenceInstructions <= 455 DCHECK(Assembler::kJSReturnSequenceInstructions <=
456 masm_->InstructionsGeneratedSince(&check_exit_codesize)); 456 masm_->InstructionsGeneratedSince(&check_exit_codesize));
457 #endif 457 #endif
458 } 458 }
459 } 459 }
460 460
461 461
462 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { 462 void FullCodeGenerator::EffectContext::Plug(Variable* var) const {
463 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 463 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
464 } 464 }
465 465
466 466
467 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { 467 void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const {
468 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 468 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
469 codegen()->GetVar(result_register(), var); 469 codegen()->GetVar(result_register(), var);
470 } 470 }
471 471
472 472
473 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 473 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
474 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 474 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
475 codegen()->GetVar(result_register(), var); 475 codegen()->GetVar(result_register(), var);
476 __ push(result_register()); 476 __ push(result_register());
477 } 477 }
478 478
479 479
480 void FullCodeGenerator::TestContext::Plug(Variable* var) const { 480 void FullCodeGenerator::TestContext::Plug(Variable* var) const {
481 // For simplicity we always test the accumulator register. 481 // For simplicity we always test the accumulator register.
482 codegen()->GetVar(result_register(), var); 482 codegen()->GetVar(result_register(), var);
483 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 483 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
484 codegen()->DoTest(this); 484 codegen()->DoTest(this);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 __ li(result_register(), Operand(lit)); 535 __ li(result_register(), Operand(lit));
536 __ push(result_register()); 536 __ push(result_register());
537 } 537 }
538 538
539 539
540 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 540 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
541 codegen()->PrepareForBailoutBeforeSplit(condition(), 541 codegen()->PrepareForBailoutBeforeSplit(condition(),
542 true, 542 true,
543 true_label_, 543 true_label_,
544 false_label_); 544 false_label_);
545 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. 545 DCHECK(!lit->IsUndetectableObject()); // There are no undetectable literals.
546 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 546 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
547 if (false_label_ != fall_through_) __ Branch(false_label_); 547 if (false_label_ != fall_through_) __ Branch(false_label_);
548 } else if (lit->IsTrue() || lit->IsJSObject()) { 548 } else if (lit->IsTrue() || lit->IsJSObject()) {
549 if (true_label_ != fall_through_) __ Branch(true_label_); 549 if (true_label_ != fall_through_) __ Branch(true_label_);
550 } else if (lit->IsString()) { 550 } else if (lit->IsString()) {
551 if (String::cast(*lit)->length() == 0) { 551 if (String::cast(*lit)->length() == 0) {
552 if (false_label_ != fall_through_) __ Branch(false_label_); 552 if (false_label_ != fall_through_) __ Branch(false_label_);
553 } else { 553 } else {
554 if (true_label_ != fall_through_) __ Branch(true_label_); 554 if (true_label_ != fall_through_) __ Branch(true_label_);
555 } 555 }
556 } else if (lit->IsSmi()) { 556 } else if (lit->IsSmi()) {
557 if (Smi::cast(*lit)->value() == 0) { 557 if (Smi::cast(*lit)->value() == 0) {
558 if (false_label_ != fall_through_) __ Branch(false_label_); 558 if (false_label_ != fall_through_) __ Branch(false_label_);
559 } else { 559 } else {
560 if (true_label_ != fall_through_) __ Branch(true_label_); 560 if (true_label_ != fall_through_) __ Branch(true_label_);
561 } 561 }
562 } else { 562 } else {
563 // For simplicity we always test the accumulator register. 563 // For simplicity we always test the accumulator register.
564 __ li(result_register(), Operand(lit)); 564 __ li(result_register(), Operand(lit));
565 codegen()->DoTest(this); 565 codegen()->DoTest(this);
566 } 566 }
567 } 567 }
568 568
569 569
570 void FullCodeGenerator::EffectContext::DropAndPlug(int count, 570 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
571 Register reg) const { 571 Register reg) const {
572 ASSERT(count > 0); 572 DCHECK(count > 0);
573 __ Drop(count); 573 __ Drop(count);
574 } 574 }
575 575
576 576
577 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 577 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
578 int count, 578 int count,
579 Register reg) const { 579 Register reg) const {
580 ASSERT(count > 0); 580 DCHECK(count > 0);
581 __ Drop(count); 581 __ Drop(count);
582 __ Move(result_register(), reg); 582 __ Move(result_register(), reg);
583 } 583 }
584 584
585 585
586 void FullCodeGenerator::StackValueContext::DropAndPlug(int count, 586 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
587 Register reg) const { 587 Register reg) const {
588 ASSERT(count > 0); 588 DCHECK(count > 0);
589 if (count > 1) __ Drop(count - 1); 589 if (count > 1) __ Drop(count - 1);
590 __ sw(reg, MemOperand(sp, 0)); 590 __ sw(reg, MemOperand(sp, 0));
591 } 591 }
592 592
593 593
594 void FullCodeGenerator::TestContext::DropAndPlug(int count, 594 void FullCodeGenerator::TestContext::DropAndPlug(int count,
595 Register reg) const { 595 Register reg) const {
596 ASSERT(count > 0); 596 DCHECK(count > 0);
597 // For simplicity we always test the accumulator register. 597 // For simplicity we always test the accumulator register.
598 __ Drop(count); 598 __ Drop(count);
599 __ Move(result_register(), reg); 599 __ Move(result_register(), reg);
600 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 600 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
601 codegen()->DoTest(this); 601 codegen()->DoTest(this);
602 } 602 }
603 603
604 604
605 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 605 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
606 Label* materialize_false) const { 606 Label* materialize_false) const {
607 ASSERT(materialize_true == materialize_false); 607 DCHECK(materialize_true == materialize_false);
608 __ bind(materialize_true); 608 __ bind(materialize_true);
609 } 609 }
610 610
611 611
612 void FullCodeGenerator::AccumulatorValueContext::Plug( 612 void FullCodeGenerator::AccumulatorValueContext::Plug(
613 Label* materialize_true, 613 Label* materialize_true,
614 Label* materialize_false) const { 614 Label* materialize_false) const {
615 Label done; 615 Label done;
616 __ bind(materialize_true); 616 __ bind(materialize_true);
617 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); 617 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
(...skipping 15 matching lines...) Expand all
633 __ Branch(&done); 633 __ Branch(&done);
634 __ bind(materialize_false); 634 __ bind(materialize_false);
635 __ LoadRoot(at, Heap::kFalseValueRootIndex); 635 __ LoadRoot(at, Heap::kFalseValueRootIndex);
636 __ push(at); 636 __ push(at);
637 __ bind(&done); 637 __ bind(&done);
638 } 638 }
639 639
640 640
641 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 641 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
642 Label* materialize_false) const { 642 Label* materialize_false) const {
643 ASSERT(materialize_true == true_label_); 643 DCHECK(materialize_true == true_label_);
644 ASSERT(materialize_false == false_label_); 644 DCHECK(materialize_false == false_label_);
645 } 645 }
646 646
647 647
648 void FullCodeGenerator::EffectContext::Plug(bool flag) const { 648 void FullCodeGenerator::EffectContext::Plug(bool flag) const {
649 } 649 }
650 650
651 651
652 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 652 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
653 Heap::RootListIndex value_root_index = 653 Heap::RootListIndex value_root_index =
654 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; 654 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 } else if (if_true == fall_through) { 700 } else if (if_true == fall_through) {
701 __ Branch(if_false, NegateCondition(cc), lhs, rhs); 701 __ Branch(if_false, NegateCondition(cc), lhs, rhs);
702 } else { 702 } else {
703 __ Branch(if_true, cc, lhs, rhs); 703 __ Branch(if_true, cc, lhs, rhs);
704 __ Branch(if_false); 704 __ Branch(if_false);
705 } 705 }
706 } 706 }
707 707
708 708
709 MemOperand FullCodeGenerator::StackOperand(Variable* var) { 709 MemOperand FullCodeGenerator::StackOperand(Variable* var) {
710 ASSERT(var->IsStackAllocated()); 710 DCHECK(var->IsStackAllocated());
711 // Offset is negative because higher indexes are at lower addresses. 711 // Offset is negative because higher indexes are at lower addresses.
712 int offset = -var->index() * kPointerSize; 712 int offset = -var->index() * kPointerSize;
713 // Adjust by a (parameter or local) base offset. 713 // Adjust by a (parameter or local) base offset.
714 if (var->IsParameter()) { 714 if (var->IsParameter()) {
715 offset += (info_->scope()->num_parameters() + 1) * kPointerSize; 715 offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
716 } else { 716 } else {
717 offset += JavaScriptFrameConstants::kLocal0Offset; 717 offset += JavaScriptFrameConstants::kLocal0Offset;
718 } 718 }
719 return MemOperand(fp, offset); 719 return MemOperand(fp, offset);
720 } 720 }
721 721
722 722
723 MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) { 723 MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) {
724 ASSERT(var->IsContextSlot() || var->IsStackAllocated()); 724 DCHECK(var->IsContextSlot() || var->IsStackAllocated());
725 if (var->IsContextSlot()) { 725 if (var->IsContextSlot()) {
726 int context_chain_length = scope()->ContextChainLength(var->scope()); 726 int context_chain_length = scope()->ContextChainLength(var->scope());
727 __ LoadContext(scratch, context_chain_length); 727 __ LoadContext(scratch, context_chain_length);
728 return ContextOperand(scratch, var->index()); 728 return ContextOperand(scratch, var->index());
729 } else { 729 } else {
730 return StackOperand(var); 730 return StackOperand(var);
731 } 731 }
732 } 732 }
733 733
734 734
735 void FullCodeGenerator::GetVar(Register dest, Variable* var) { 735 void FullCodeGenerator::GetVar(Register dest, Variable* var) {
736 // Use destination as scratch. 736 // Use destination as scratch.
737 MemOperand location = VarOperand(var, dest); 737 MemOperand location = VarOperand(var, dest);
738 __ lw(dest, location); 738 __ lw(dest, location);
739 } 739 }
740 740
741 741
742 void FullCodeGenerator::SetVar(Variable* var, 742 void FullCodeGenerator::SetVar(Variable* var,
743 Register src, 743 Register src,
744 Register scratch0, 744 Register scratch0,
745 Register scratch1) { 745 Register scratch1) {
746 ASSERT(var->IsContextSlot() || var->IsStackAllocated()); 746 DCHECK(var->IsContextSlot() || var->IsStackAllocated());
747 ASSERT(!scratch0.is(src)); 747 DCHECK(!scratch0.is(src));
748 ASSERT(!scratch0.is(scratch1)); 748 DCHECK(!scratch0.is(scratch1));
749 ASSERT(!scratch1.is(src)); 749 DCHECK(!scratch1.is(src));
750 MemOperand location = VarOperand(var, scratch0); 750 MemOperand location = VarOperand(var, scratch0);
751 __ sw(src, location); 751 __ sw(src, location);
752 // Emit the write barrier code if the location is in the heap. 752 // Emit the write barrier code if the location is in the heap.
753 if (var->IsContextSlot()) { 753 if (var->IsContextSlot()) {
754 __ RecordWriteContextSlot(scratch0, 754 __ RecordWriteContextSlot(scratch0,
755 location.offset(), 755 location.offset(),
756 src, 756 src,
757 scratch1, 757 scratch1,
758 kRAHasBeenSaved, 758 kRAHasBeenSaved,
759 kDontSaveFPRegs); 759 kDontSaveFPRegs);
(...skipping 17 matching lines...) Expand all
777 __ LoadRoot(t0, Heap::kTrueValueRootIndex); 777 __ LoadRoot(t0, Heap::kTrueValueRootIndex);
778 Split(eq, a0, Operand(t0), if_true, if_false, NULL); 778 Split(eq, a0, Operand(t0), if_true, if_false, NULL);
779 __ bind(&skip); 779 __ bind(&skip);
780 } 780 }
781 } 781 }
782 782
783 783
784 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 784 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
785 // The variable in the declaration always resides in the current function 785 // The variable in the declaration always resides in the current function
786 // context. 786 // context.
787 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 787 DCHECK_EQ(0, scope()->ContextChainLength(variable->scope()));
788 if (generate_debug_code_) { 788 if (generate_debug_code_) {
789 // Check that we're not inside a with or catch context. 789 // Check that we're not inside a with or catch context.
790 __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset)); 790 __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset));
791 __ LoadRoot(t0, Heap::kWithContextMapRootIndex); 791 __ LoadRoot(t0, Heap::kWithContextMapRootIndex);
792 __ Check(ne, kDeclarationInWithContext, 792 __ Check(ne, kDeclarationInWithContext,
793 a1, Operand(t0)); 793 a1, Operand(t0));
794 __ LoadRoot(t0, Heap::kCatchContextMapRootIndex); 794 __ LoadRoot(t0, Heap::kCatchContextMapRootIndex);
795 __ Check(ne, kDeclarationInCatchContext, 795 __ Check(ne, kDeclarationInCatchContext,
796 a1, Operand(t0)); 796 a1, Operand(t0));
797 } 797 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 __ sw(at, ContextOperand(cp, variable->index())); 833 __ sw(at, ContextOperand(cp, variable->index()));
834 // No write barrier since the_hole_value is in old space. 834 // No write barrier since the_hole_value is in old space.
835 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 835 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
836 } 836 }
837 break; 837 break;
838 838
839 case Variable::LOOKUP: { 839 case Variable::LOOKUP: {
840 Comment cmnt(masm_, "[ VariableDeclaration"); 840 Comment cmnt(masm_, "[ VariableDeclaration");
841 __ li(a2, Operand(variable->name())); 841 __ li(a2, Operand(variable->name()));
842 // Declaration nodes are always introduced in one of four modes. 842 // Declaration nodes are always introduced in one of four modes.
843 ASSERT(IsDeclaredVariableMode(mode)); 843 DCHECK(IsDeclaredVariableMode(mode));
844 PropertyAttributes attr = 844 PropertyAttributes attr =
845 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; 845 IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
846 __ li(a1, Operand(Smi::FromInt(attr))); 846 __ li(a1, Operand(Smi::FromInt(attr)));
847 // Push initial value, if any. 847 // Push initial value, if any.
848 // Note: For variables we must not push an initial value (such as 848 // Note: For variables we must not push an initial value (such as
849 // 'undefined') because we may have a (legal) redeclaration and we 849 // 'undefined') because we may have a (legal) redeclaration and we
850 // must not destroy the current value. 850 // must not destroy the current value.
851 if (hole_init) { 851 if (hole_init) {
852 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); 852 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
853 __ Push(cp, a2, a1, a0); 853 __ Push(cp, a2, a1, a0);
854 } else { 854 } else {
855 ASSERT(Smi::FromInt(0) == 0); 855 DCHECK(Smi::FromInt(0) == 0);
856 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. 856 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value.
857 __ Push(cp, a2, a1, a0); 857 __ Push(cp, a2, a1, a0);
858 } 858 }
859 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); 859 __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
860 break; 860 break;
861 } 861 }
862 } 862 }
863 } 863 }
864 864
865 865
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 VisitForStackValue(declaration->fun()); 914 VisitForStackValue(declaration->fun());
915 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); 915 __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
916 break; 916 break;
917 } 917 }
918 } 918 }
919 } 919 }
920 920
921 921
922 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { 922 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
923 Variable* variable = declaration->proxy()->var(); 923 Variable* variable = declaration->proxy()->var();
924 ASSERT(variable->location() == Variable::CONTEXT); 924 DCHECK(variable->location() == Variable::CONTEXT);
925 ASSERT(variable->interface()->IsFrozen()); 925 DCHECK(variable->interface()->IsFrozen());
926 926
927 Comment cmnt(masm_, "[ ModuleDeclaration"); 927 Comment cmnt(masm_, "[ ModuleDeclaration");
928 EmitDebugCheckDeclarationContext(variable); 928 EmitDebugCheckDeclarationContext(variable);
929 929
930 // Load instance object. 930 // Load instance object.
931 __ LoadContext(a1, scope_->ContextChainLength(scope_->GlobalScope())); 931 __ LoadContext(a1, scope_->ContextChainLength(scope_->GlobalScope()));
932 __ lw(a1, ContextOperand(a1, variable->interface()->Index())); 932 __ lw(a1, ContextOperand(a1, variable->interface()->Index()));
933 __ lw(a1, ContextOperand(a1, Context::EXTENSION_INDEX)); 933 __ lw(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
934 934
935 // Assign it. 935 // Assign it.
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 1214
1215 // Check if the expected map still matches that of the enumerable. 1215 // Check if the expected map still matches that of the enumerable.
1216 // If not, we may have to filter the key. 1216 // If not, we may have to filter the key.
1217 Label update_each; 1217 Label update_each;
1218 __ lw(a1, MemOperand(sp, 4 * kPointerSize)); 1218 __ lw(a1, MemOperand(sp, 4 * kPointerSize));
1219 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); 1219 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset));
1220 __ Branch(&update_each, eq, t0, Operand(a2)); 1220 __ Branch(&update_each, eq, t0, Operand(a2));
1221 1221
1222 // For proxies, no filtering is done. 1222 // For proxies, no filtering is done.
1223 // TODO(rossberg): What if only a prototype is a proxy? Not specified yet. 1223 // TODO(rossberg): What if only a prototype is a proxy? Not specified yet.
1224 ASSERT_EQ(Smi::FromInt(0), 0); 1224 DCHECK_EQ(Smi::FromInt(0), 0);
1225 __ Branch(&update_each, eq, a2, Operand(zero_reg)); 1225 __ Branch(&update_each, eq, a2, Operand(zero_reg));
1226 1226
1227 // Convert the entry to a string or (smi) 0 if it isn't a property 1227 // Convert the entry to a string or (smi) 0 if it isn't a property
1228 // any more. If the property has been removed while iterating, we 1228 // any more. If the property has been removed while iterating, we
1229 // just skip it. 1229 // just skip it.
1230 __ Push(a1, a3); // Enumerable and current entry. 1230 __ Push(a1, a3); // Enumerable and current entry.
1231 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 1231 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
1232 __ mov(a3, result_register()); 1232 __ mov(a3, result_register());
1233 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); 1233 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg));
1234 1234
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 1396
1397 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) 1397 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1398 ? NOT_CONTEXTUAL 1398 ? NOT_CONTEXTUAL
1399 : CONTEXTUAL; 1399 : CONTEXTUAL;
1400 CallLoadIC(mode); 1400 CallLoadIC(mode);
1401 } 1401 }
1402 1402
1403 1403
1404 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1404 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1405 Label* slow) { 1405 Label* slow) {
1406 ASSERT(var->IsContextSlot()); 1406 DCHECK(var->IsContextSlot());
1407 Register context = cp; 1407 Register context = cp;
1408 Register next = a3; 1408 Register next = a3;
1409 Register temp = t0; 1409 Register temp = t0;
1410 1410
1411 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1411 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1412 if (s->num_heap_slots() > 0) { 1412 if (s->num_heap_slots() > 0) {
1413 if (s->calls_sloppy_eval()) { 1413 if (s->calls_sloppy_eval()) {
1414 // Check that extension is NULL. 1414 // Check that extension is NULL.
1415 __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX)); 1415 __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX));
1416 __ Branch(slow, ne, temp, Operand(zero_reg)); 1416 __ Branch(slow, ne, temp, Operand(zero_reg));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 case Variable::LOCAL: 1491 case Variable::LOCAL:
1492 case Variable::CONTEXT: { 1492 case Variable::CONTEXT: {
1493 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1493 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1494 : "[ Stack variable"); 1494 : "[ Stack variable");
1495 if (var->binding_needs_init()) { 1495 if (var->binding_needs_init()) {
1496 // var->scope() may be NULL when the proxy is located in eval code and 1496 // var->scope() may be NULL when the proxy is located in eval code and
1497 // refers to a potential outside binding. Currently those bindings are 1497 // refers to a potential outside binding. Currently those bindings are
1498 // always looked up dynamically, i.e. in that case 1498 // always looked up dynamically, i.e. in that case
1499 // var->location() == LOOKUP. 1499 // var->location() == LOOKUP.
1500 // always holds. 1500 // always holds.
1501 ASSERT(var->scope() != NULL); 1501 DCHECK(var->scope() != NULL);
1502 1502
1503 // Check if the binding really needs an initialization check. The check 1503 // Check if the binding really needs an initialization check. The check
1504 // can be skipped in the following situation: we have a LET or CONST 1504 // can be skipped in the following situation: we have a LET or CONST
1505 // binding in harmony mode, both the Variable and the VariableProxy have 1505 // binding in harmony mode, both the Variable and the VariableProxy have
1506 // the same declaration scope (i.e. they are both in global code, in the 1506 // the same declaration scope (i.e. they are both in global code, in the
1507 // same function or in the same eval code) and the VariableProxy is in 1507 // same function or in the same eval code) and the VariableProxy is in
1508 // the source physically located after the initializer of the variable. 1508 // the source physically located after the initializer of the variable.
1509 // 1509 //
1510 // We cannot skip any initialization checks for CONST in non-harmony 1510 // We cannot skip any initialization checks for CONST in non-harmony
1511 // mode because const variables may be declared but never initialized: 1511 // mode because const variables may be declared but never initialized:
1512 // if (false) { const x; }; var y = x; 1512 // if (false) { const x; }; var y = x;
1513 // 1513 //
1514 // The condition on the declaration scopes is a conservative check for 1514 // The condition on the declaration scopes is a conservative check for
1515 // nested functions that access a binding and are called before the 1515 // nested functions that access a binding and are called before the
1516 // binding is initialized: 1516 // binding is initialized:
1517 // function() { f(); let x = 1; function f() { x = 2; } } 1517 // function() { f(); let x = 1; function f() { x = 2; } }
1518 // 1518 //
1519 bool skip_init_check; 1519 bool skip_init_check;
1520 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1520 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1521 skip_init_check = false; 1521 skip_init_check = false;
1522 } else { 1522 } else {
1523 // Check that we always have valid source position. 1523 // Check that we always have valid source position.
1524 ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1524 DCHECK(var->initializer_position() != RelocInfo::kNoPosition);
1525 ASSERT(proxy->position() != RelocInfo::kNoPosition); 1525 DCHECK(proxy->position() != RelocInfo::kNoPosition);
1526 skip_init_check = var->mode() != CONST_LEGACY && 1526 skip_init_check = var->mode() != CONST_LEGACY &&
1527 var->initializer_position() < proxy->position(); 1527 var->initializer_position() < proxy->position();
1528 } 1528 }
1529 1529
1530 if (!skip_init_check) { 1530 if (!skip_init_check) {
1531 // Let and const need a read barrier. 1531 // Let and const need a read barrier.
1532 GetVar(v0, var); 1532 GetVar(v0, var);
1533 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1533 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1534 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1534 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1535 if (var->mode() == LET || var->mode() == CONST) { 1535 if (var->mode() == LET || var->mode() == CONST) {
1536 // Throw a reference error when using an uninitialized let/const 1536 // Throw a reference error when using an uninitialized let/const
1537 // binding in harmony mode. 1537 // binding in harmony mode.
1538 Label done; 1538 Label done;
1539 __ Branch(&done, ne, at, Operand(zero_reg)); 1539 __ Branch(&done, ne, at, Operand(zero_reg));
1540 __ li(a0, Operand(var->name())); 1540 __ li(a0, Operand(var->name()));
1541 __ push(a0); 1541 __ push(a0);
1542 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1542 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1543 __ bind(&done); 1543 __ bind(&done);
1544 } else { 1544 } else {
1545 // Uninitalized const bindings outside of harmony mode are unholed. 1545 // Uninitalized const bindings outside of harmony mode are unholed.
1546 ASSERT(var->mode() == CONST_LEGACY); 1546 DCHECK(var->mode() == CONST_LEGACY);
1547 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1547 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1548 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole. 1548 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole.
1549 } 1549 }
1550 context()->Plug(v0); 1550 context()->Plug(v0);
1551 break; 1551 break;
1552 } 1552 }
1553 } 1553 }
1554 context()->Plug(var); 1554 context()->Plug(var);
1555 break; 1555 break;
1556 } 1556 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 Literal* key = property->key(); 1676 Literal* key = property->key();
1677 Expression* value = property->value(); 1677 Expression* value = property->value();
1678 if (!result_saved) { 1678 if (!result_saved) {
1679 __ push(v0); // Save result on stack. 1679 __ push(v0); // Save result on stack.
1680 result_saved = true; 1680 result_saved = true;
1681 } 1681 }
1682 switch (property->kind()) { 1682 switch (property->kind()) {
1683 case ObjectLiteral::Property::CONSTANT: 1683 case ObjectLiteral::Property::CONSTANT:
1684 UNREACHABLE(); 1684 UNREACHABLE();
1685 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1685 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1686 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1686 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1687 // Fall through. 1687 // Fall through.
1688 case ObjectLiteral::Property::COMPUTED: 1688 case ObjectLiteral::Property::COMPUTED:
1689 if (key->value()->IsInternalizedString()) { 1689 if (key->value()->IsInternalizedString()) {
1690 if (property->emit_store()) { 1690 if (property->emit_store()) {
1691 VisitForAccumulatorValue(value); 1691 VisitForAccumulatorValue(value);
1692 __ mov(StoreIC::ValueRegister(), result_register()); 1692 __ mov(StoreIC::ValueRegister(), result_register());
1693 ASSERT(StoreIC::ValueRegister().is(a0)); 1693 DCHECK(StoreIC::ValueRegister().is(a0));
1694 __ li(StoreIC::NameRegister(), Operand(key->value())); 1694 __ li(StoreIC::NameRegister(), Operand(key->value()));
1695 __ lw(StoreIC::ReceiverRegister(), MemOperand(sp)); 1695 __ lw(StoreIC::ReceiverRegister(), MemOperand(sp));
1696 CallStoreIC(key->LiteralFeedbackId()); 1696 CallStoreIC(key->LiteralFeedbackId());
1697 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1697 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1698 } else { 1698 } else {
1699 VisitForEffect(value); 1699 VisitForEffect(value);
1700 } 1700 }
1701 break; 1701 break;
1702 } 1702 }
1703 // Duplicate receiver on stack. 1703 // Duplicate receiver on stack.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 __ push(a0); 1742 __ push(a0);
1743 VisitForStackValue(it->first); 1743 VisitForStackValue(it->first);
1744 EmitAccessor(it->second->getter); 1744 EmitAccessor(it->second->getter);
1745 EmitAccessor(it->second->setter); 1745 EmitAccessor(it->second->setter);
1746 __ li(a0, Operand(Smi::FromInt(NONE))); 1746 __ li(a0, Operand(Smi::FromInt(NONE)));
1747 __ push(a0); 1747 __ push(a0);
1748 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1748 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1749 } 1749 }
1750 1750
1751 if (expr->has_function()) { 1751 if (expr->has_function()) {
1752 ASSERT(result_saved); 1752 DCHECK(result_saved);
1753 __ lw(a0, MemOperand(sp)); 1753 __ lw(a0, MemOperand(sp));
1754 __ push(a0); 1754 __ push(a0);
1755 __ CallRuntime(Runtime::kToFastProperties, 1); 1755 __ CallRuntime(Runtime::kToFastProperties, 1);
1756 } 1756 }
1757 1757
1758 if (result_saved) { 1758 if (result_saved) {
1759 context()->PlugTOS(); 1759 context()->PlugTOS();
1760 } else { 1760 } else {
1761 context()->Plug(v0); 1761 context()->Plug(v0);
1762 } 1762 }
1763 } 1763 }
1764 1764
1765 1765
1766 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1766 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1767 Comment cmnt(masm_, "[ ArrayLiteral"); 1767 Comment cmnt(masm_, "[ ArrayLiteral");
1768 1768
1769 expr->BuildConstantElements(isolate()); 1769 expr->BuildConstantElements(isolate());
1770 int flags = expr->depth() == 1 1770 int flags = expr->depth() == 1
1771 ? ArrayLiteral::kShallowElements 1771 ? ArrayLiteral::kShallowElements
1772 : ArrayLiteral::kNoFlags; 1772 : ArrayLiteral::kNoFlags;
1773 1773
1774 ZoneList<Expression*>* subexprs = expr->values(); 1774 ZoneList<Expression*>* subexprs = expr->values();
1775 int length = subexprs->length(); 1775 int length = subexprs->length();
1776 1776
1777 Handle<FixedArray> constant_elements = expr->constant_elements(); 1777 Handle<FixedArray> constant_elements = expr->constant_elements();
1778 ASSERT_EQ(2, constant_elements->length()); 1778 DCHECK_EQ(2, constant_elements->length());
1779 ElementsKind constant_elements_kind = 1779 ElementsKind constant_elements_kind =
1780 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); 1780 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
1781 bool has_fast_elements = 1781 bool has_fast_elements =
1782 IsFastObjectElementsKind(constant_elements_kind); 1782 IsFastObjectElementsKind(constant_elements_kind);
1783 Handle<FixedArrayBase> constant_elements_values( 1783 Handle<FixedArrayBase> constant_elements_values(
1784 FixedArrayBase::cast(constant_elements->get(1))); 1784 FixedArrayBase::cast(constant_elements->get(1)));
1785 1785
1786 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE; 1786 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
1787 if (has_fast_elements && !FLAG_allocation_site_pretenuring) { 1787 if (has_fast_elements && !FLAG_allocation_site_pretenuring) {
1788 // If the only customer of allocation sites is transitioning, then 1788 // If the only customer of allocation sites is transitioning, then
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 if (result_saved) { 1843 if (result_saved) {
1844 __ Pop(); // literal index 1844 __ Pop(); // literal index
1845 context()->PlugTOS(); 1845 context()->PlugTOS();
1846 } else { 1846 } else {
1847 context()->Plug(v0); 1847 context()->Plug(v0);
1848 } 1848 }
1849 } 1849 }
1850 1850
1851 1851
1852 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1852 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1853 ASSERT(expr->target()->IsValidReferenceExpression()); 1853 DCHECK(expr->target()->IsValidReferenceExpression());
1854 1854
1855 Comment cmnt(masm_, "[ Assignment"); 1855 Comment cmnt(masm_, "[ Assignment");
1856 1856
1857 // Left-hand side can only be a property, a global or a (parameter or local) 1857 // Left-hand side can only be a property, a global or a (parameter or local)
1858 // slot. 1858 // slot.
1859 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1859 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1860 LhsKind assign_type = VARIABLE; 1860 LhsKind assign_type = VARIABLE;
1861 Property* property = expr->target()->AsProperty(); 1861 Property* property = expr->target()->AsProperty();
1862 if (property != NULL) { 1862 if (property != NULL) {
1863 assign_type = (property->key()->IsPropertyName()) 1863 assign_type = (property->key()->IsPropertyName())
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1974 case Yield::INITIAL: { 1974 case Yield::INITIAL: {
1975 Label suspend, continuation, post_runtime, resume; 1975 Label suspend, continuation, post_runtime, resume;
1976 1976
1977 __ jmp(&suspend); 1977 __ jmp(&suspend);
1978 1978
1979 __ bind(&continuation); 1979 __ bind(&continuation);
1980 __ jmp(&resume); 1980 __ jmp(&resume);
1981 1981
1982 __ bind(&suspend); 1982 __ bind(&suspend);
1983 VisitForAccumulatorValue(expr->generator_object()); 1983 VisitForAccumulatorValue(expr->generator_object());
1984 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1984 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1985 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); 1985 __ li(a1, Operand(Smi::FromInt(continuation.pos())));
1986 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); 1986 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset));
1987 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); 1987 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
1988 __ mov(a1, cp); 1988 __ mov(a1, cp);
1989 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, 1989 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
1990 kRAHasBeenSaved, kDontSaveFPRegs); 1990 kRAHasBeenSaved, kDontSaveFPRegs);
1991 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1991 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1992 __ Branch(&post_runtime, eq, sp, Operand(a1)); 1992 __ Branch(&post_runtime, eq, sp, Operand(a1));
1993 __ push(v0); // generator object 1993 __ push(v0); // generator object
1994 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1994 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 const int handler_size = StackHandlerConstants::kSize; 2048 const int handler_size = StackHandlerConstants::kSize;
2049 __ push(a0); // result 2049 __ push(a0); // result
2050 __ jmp(&l_suspend); 2050 __ jmp(&l_suspend);
2051 __ bind(&l_continuation); 2051 __ bind(&l_continuation);
2052 __ mov(a0, v0); 2052 __ mov(a0, v0);
2053 __ jmp(&l_resume); 2053 __ jmp(&l_resume);
2054 __ bind(&l_suspend); 2054 __ bind(&l_suspend);
2055 const int generator_object_depth = kPointerSize + handler_size; 2055 const int generator_object_depth = kPointerSize + handler_size;
2056 __ lw(a0, MemOperand(sp, generator_object_depth)); 2056 __ lw(a0, MemOperand(sp, generator_object_depth));
2057 __ push(a0); // g 2057 __ push(a0); // g
2058 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); 2058 DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
2059 __ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); 2059 __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
2060 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); 2060 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
2061 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset)); 2061 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset));
2062 __ mov(a1, cp); 2062 __ mov(a1, cp);
2063 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, 2063 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2,
2064 kRAHasBeenSaved, kDontSaveFPRegs); 2064 kRAHasBeenSaved, kDontSaveFPRegs);
2065 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2065 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2066 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2066 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2067 __ pop(v0); // result 2067 __ pop(v0); // result
2068 EmitReturnSequence(); 2068 EmitReturnSequence();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 2202
2203 // Otherwise, we push holes for the operand stack and call the runtime to fix 2203 // Otherwise, we push holes for the operand stack and call the runtime to fix
2204 // up the stack and the handlers. 2204 // up the stack and the handlers.
2205 Label push_operand_holes, call_resume; 2205 Label push_operand_holes, call_resume;
2206 __ bind(&push_operand_holes); 2206 __ bind(&push_operand_holes);
2207 __ Subu(a3, a3, Operand(1)); 2207 __ Subu(a3, a3, Operand(1));
2208 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); 2208 __ Branch(&call_resume, lt, a3, Operand(zero_reg));
2209 __ push(a2); 2209 __ push(a2);
2210 __ Branch(&push_operand_holes); 2210 __ Branch(&push_operand_holes);
2211 __ bind(&call_resume); 2211 __ bind(&call_resume);
2212 ASSERT(!result_register().is(a1)); 2212 DCHECK(!result_register().is(a1));
2213 __ Push(a1, result_register()); 2213 __ Push(a1, result_register());
2214 __ Push(Smi::FromInt(resume_mode)); 2214 __ Push(Smi::FromInt(resume_mode));
2215 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2215 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2216 // Not reached: the runtime call returns elsewhere. 2216 // Not reached: the runtime call returns elsewhere.
2217 __ stop("not-reached"); 2217 __ stop("not-reached");
2218 2218
2219 // Reach here when generator is closed. 2219 // Reach here when generator is closed.
2220 __ bind(&closed_state); 2220 __ bind(&closed_state);
2221 if (resume_mode == JSGeneratorObject::NEXT) { 2221 if (resume_mode == JSGeneratorObject::NEXT) {
2222 // Return completed iterator result when generator is closed. 2222 // Return completed iterator result when generator is closed.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 __ Push(Smi::FromInt(map->instance_size())); 2254 __ Push(Smi::FromInt(map->instance_size()));
2255 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 2255 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2256 __ lw(context_register(), 2256 __ lw(context_register(),
2257 MemOperand(fp, StandardFrameConstants::kContextOffset)); 2257 MemOperand(fp, StandardFrameConstants::kContextOffset));
2258 2258
2259 __ bind(&allocated); 2259 __ bind(&allocated);
2260 __ li(a1, Operand(map)); 2260 __ li(a1, Operand(map));
2261 __ pop(a2); 2261 __ pop(a2);
2262 __ li(a3, Operand(isolate()->factory()->ToBoolean(done))); 2262 __ li(a3, Operand(isolate()->factory()->ToBoolean(done)));
2263 __ li(t0, Operand(isolate()->factory()->empty_fixed_array())); 2263 __ li(t0, Operand(isolate()->factory()->empty_fixed_array()));
2264 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); 2264 DCHECK_EQ(map->instance_size(), 5 * kPointerSize);
2265 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 2265 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
2266 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 2266 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset));
2267 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); 2267 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
2268 __ sw(a2, 2268 __ sw(a2,
2269 FieldMemOperand(v0, JSGeneratorObject::kResultValuePropertyOffset)); 2269 FieldMemOperand(v0, JSGeneratorObject::kResultValuePropertyOffset));
2270 __ sw(a3, 2270 __ sw(a3,
2271 FieldMemOperand(v0, JSGeneratorObject::kResultDonePropertyOffset)); 2271 FieldMemOperand(v0, JSGeneratorObject::kResultDonePropertyOffset));
2272 2272
2273 // Only the value field needs a write barrier, as the other values are in the 2273 // Only the value field needs a write barrier, as the other values are in the
2274 // root set. 2274 // root set.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2371 __ SmiUntag(scratch1, right); 2371 __ SmiUntag(scratch1, right);
2372 __ Mult(left, scratch1); 2372 __ Mult(left, scratch1);
2373 __ mflo(scratch1); 2373 __ mflo(scratch1);
2374 __ mfhi(scratch2); 2374 __ mfhi(scratch2);
2375 __ sra(scratch1, scratch1, 31); 2375 __ sra(scratch1, scratch1, 31);
2376 __ Branch(&stub_call, ne, scratch1, Operand(scratch2)); 2376 __ Branch(&stub_call, ne, scratch1, Operand(scratch2));
2377 __ mflo(v0); 2377 __ mflo(v0);
2378 __ Branch(&done, ne, v0, Operand(zero_reg)); 2378 __ Branch(&done, ne, v0, Operand(zero_reg));
2379 __ Addu(scratch2, right, left); 2379 __ Addu(scratch2, right, left);
2380 __ Branch(&stub_call, lt, scratch2, Operand(zero_reg)); 2380 __ Branch(&stub_call, lt, scratch2, Operand(zero_reg));
2381 ASSERT(Smi::FromInt(0) == 0); 2381 DCHECK(Smi::FromInt(0) == 0);
2382 __ mov(v0, zero_reg); 2382 __ mov(v0, zero_reg);
2383 break; 2383 break;
2384 } 2384 }
2385 case Token::BIT_OR: 2385 case Token::BIT_OR:
2386 __ Or(v0, left, Operand(right)); 2386 __ Or(v0, left, Operand(right));
2387 break; 2387 break;
2388 case Token::BIT_AND: 2388 case Token::BIT_AND:
2389 __ And(v0, left, Operand(right)); 2389 __ And(v0, left, Operand(right));
2390 break; 2390 break;
2391 case Token::BIT_XOR: 2391 case Token::BIT_XOR:
(...skipping 15 matching lines...) Expand all
2407 __ pop(a1); 2407 __ pop(a1);
2408 BinaryOpICStub stub(isolate(), op, mode); 2408 BinaryOpICStub stub(isolate(), op, mode);
2409 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2409 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2410 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); 2410 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId());
2411 patch_site.EmitPatchInfo(); 2411 patch_site.EmitPatchInfo();
2412 context()->Plug(v0); 2412 context()->Plug(v0);
2413 } 2413 }
2414 2414
2415 2415
2416 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2416 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2417 ASSERT(expr->IsValidReferenceExpression()); 2417 DCHECK(expr->IsValidReferenceExpression());
2418 2418
2419 // Left-hand side can only be a property, a global or a (parameter or local) 2419 // Left-hand side can only be a property, a global or a (parameter or local)
2420 // slot. 2420 // slot.
2421 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 2421 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
2422 LhsKind assign_type = VARIABLE; 2422 LhsKind assign_type = VARIABLE;
2423 Property* prop = expr->AsProperty(); 2423 Property* prop = expr->AsProperty();
2424 if (prop != NULL) { 2424 if (prop != NULL) {
2425 assign_type = (prop->key()->IsPropertyName()) 2425 assign_type = (prop->key()->IsPropertyName())
2426 ? NAMED_PROPERTY 2426 ? NAMED_PROPERTY
2427 : KEYED_PROPERTY; 2427 : KEYED_PROPERTY;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { 2477 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
2478 if (var->IsUnallocated()) { 2478 if (var->IsUnallocated()) {
2479 // Global var, const, or let. 2479 // Global var, const, or let.
2480 __ mov(StoreIC::ValueRegister(), result_register()); 2480 __ mov(StoreIC::ValueRegister(), result_register());
2481 __ li(StoreIC::NameRegister(), Operand(var->name())); 2481 __ li(StoreIC::NameRegister(), Operand(var->name()));
2482 __ lw(StoreIC::ReceiverRegister(), GlobalObjectOperand()); 2482 __ lw(StoreIC::ReceiverRegister(), GlobalObjectOperand());
2483 CallStoreIC(); 2483 CallStoreIC();
2484 2484
2485 } else if (op == Token::INIT_CONST_LEGACY) { 2485 } else if (op == Token::INIT_CONST_LEGACY) {
2486 // Const initializers need a write barrier. 2486 // Const initializers need a write barrier.
2487 ASSERT(!var->IsParameter()); // No const parameters. 2487 DCHECK(!var->IsParameter()); // No const parameters.
2488 if (var->IsLookupSlot()) { 2488 if (var->IsLookupSlot()) {
2489 __ li(a0, Operand(var->name())); 2489 __ li(a0, Operand(var->name()));
2490 __ Push(v0, cp, a0); // Context and name. 2490 __ Push(v0, cp, a0); // Context and name.
2491 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2491 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
2492 } else { 2492 } else {
2493 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2493 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2494 Label skip; 2494 Label skip;
2495 MemOperand location = VarOperand(var, a1); 2495 MemOperand location = VarOperand(var, a1);
2496 __ lw(a2, location); 2496 __ lw(a2, location);
2497 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2497 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2498 __ Branch(&skip, ne, a2, Operand(at)); 2498 __ Branch(&skip, ne, a2, Operand(at));
2499 EmitStoreToStackLocalOrContextSlot(var, location); 2499 EmitStoreToStackLocalOrContextSlot(var, location);
2500 __ bind(&skip); 2500 __ bind(&skip);
2501 } 2501 }
2502 2502
2503 } else if (var->mode() == LET && op != Token::INIT_LET) { 2503 } else if (var->mode() == LET && op != Token::INIT_LET) {
2504 // Non-initializing assignment to let variable needs a write barrier. 2504 // Non-initializing assignment to let variable needs a write barrier.
2505 ASSERT(!var->IsLookupSlot()); 2505 DCHECK(!var->IsLookupSlot());
2506 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2506 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2507 Label assign; 2507 Label assign;
2508 MemOperand location = VarOperand(var, a1); 2508 MemOperand location = VarOperand(var, a1);
2509 __ lw(a3, location); 2509 __ lw(a3, location);
2510 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2510 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2511 __ Branch(&assign, ne, a3, Operand(t0)); 2511 __ Branch(&assign, ne, a3, Operand(t0));
2512 __ li(a3, Operand(var->name())); 2512 __ li(a3, Operand(var->name()));
2513 __ push(a3); 2513 __ push(a3);
2514 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2514 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2515 // Perform the assignment. 2515 // Perform the assignment.
2516 __ bind(&assign); 2516 __ bind(&assign);
2517 EmitStoreToStackLocalOrContextSlot(var, location); 2517 EmitStoreToStackLocalOrContextSlot(var, location);
2518 2518
2519 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { 2519 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2520 if (var->IsLookupSlot()) { 2520 if (var->IsLookupSlot()) {
2521 // Assignment to var. 2521 // Assignment to var.
2522 __ li(a1, Operand(var->name())); 2522 __ li(a1, Operand(var->name()));
2523 __ li(a0, Operand(Smi::FromInt(strict_mode()))); 2523 __ li(a0, Operand(Smi::FromInt(strict_mode())));
2524 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. 2524 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
2525 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2525 __ CallRuntime(Runtime::kStoreLookupSlot, 4);
2526 } else { 2526 } else {
2527 // Assignment to var or initializing assignment to let/const in harmony 2527 // Assignment to var or initializing assignment to let/const in harmony
2528 // mode. 2528 // mode.
2529 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); 2529 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2530 MemOperand location = VarOperand(var, a1); 2530 MemOperand location = VarOperand(var, a1);
2531 if (generate_debug_code_ && op == Token::INIT_LET) { 2531 if (generate_debug_code_ && op == Token::INIT_LET) {
2532 // Check for an uninitialized let binding. 2532 // Check for an uninitialized let binding.
2533 __ lw(a2, location); 2533 __ lw(a2, location);
2534 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2534 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2535 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0)); 2535 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2536 } 2536 }
2537 EmitStoreToStackLocalOrContextSlot(var, location); 2537 EmitStoreToStackLocalOrContextSlot(var, location);
2538 } 2538 }
2539 } 2539 }
2540 // Non-initializing assignments to consts are ignored. 2540 // Non-initializing assignments to consts are ignored.
2541 } 2541 }
2542 2542
2543 2543
2544 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2544 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2545 // Assignment to a property, using a named store IC. 2545 // Assignment to a property, using a named store IC.
2546 Property* prop = expr->target()->AsProperty(); 2546 Property* prop = expr->target()->AsProperty();
2547 ASSERT(prop != NULL); 2547 DCHECK(prop != NULL);
2548 ASSERT(prop->key()->IsLiteral()); 2548 DCHECK(prop->key()->IsLiteral());
2549 2549
2550 // Record source code position before IC call. 2550 // Record source code position before IC call.
2551 SetSourcePosition(expr->position()); 2551 SetSourcePosition(expr->position());
2552 __ mov(StoreIC::ValueRegister(), result_register()); 2552 __ mov(StoreIC::ValueRegister(), result_register());
2553 __ li(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value())); 2553 __ li(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
2554 __ pop(StoreIC::ReceiverRegister()); 2554 __ pop(StoreIC::ReceiverRegister());
2555 CallStoreIC(expr->AssignmentFeedbackId()); 2555 CallStoreIC(expr->AssignmentFeedbackId());
2556 2556
2557 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2557 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2558 context()->Plug(v0); 2558 context()->Plug(v0);
2559 } 2559 }
2560 2560
2561 2561
2562 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2562 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2563 // Assignment to a property, using a keyed store IC. 2563 // Assignment to a property, using a keyed store IC.
2564 2564
2565 // Record source code position before IC call. 2565 // Record source code position before IC call.
2566 SetSourcePosition(expr->position()); 2566 SetSourcePosition(expr->position());
2567 // Call keyed store IC. 2567 // Call keyed store IC.
2568 // The arguments are: 2568 // The arguments are:
2569 // - a0 is the value, 2569 // - a0 is the value,
2570 // - a1 is the key, 2570 // - a1 is the key,
2571 // - a2 is the receiver. 2571 // - a2 is the receiver.
2572 __ mov(KeyedStoreIC::ValueRegister(), result_register()); 2572 __ mov(KeyedStoreIC::ValueRegister(), result_register());
2573 __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister()); 2573 __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
2574 ASSERT(KeyedStoreIC::ValueRegister().is(a0)); 2574 DCHECK(KeyedStoreIC::ValueRegister().is(a0));
2575 2575
2576 Handle<Code> ic = strict_mode() == SLOPPY 2576 Handle<Code> ic = strict_mode() == SLOPPY
2577 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2577 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2578 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2578 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2579 CallIC(ic, expr->AssignmentFeedbackId()); 2579 CallIC(ic, expr->AssignmentFeedbackId());
2580 2580
2581 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2581 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2582 context()->Plug(v0); 2582 context()->Plug(v0);
2583 } 2583 }
2584 2584
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 if (call_type == CallIC::FUNCTION) { 2623 if (call_type == CallIC::FUNCTION) {
2624 { StackValueContext context(this); 2624 { StackValueContext context(this);
2625 EmitVariableLoad(callee->AsVariableProxy()); 2625 EmitVariableLoad(callee->AsVariableProxy());
2626 PrepareForBailout(callee, NO_REGISTERS); 2626 PrepareForBailout(callee, NO_REGISTERS);
2627 } 2627 }
2628 // Push undefined as receiver. This is patched in the method prologue if it 2628 // Push undefined as receiver. This is patched in the method prologue if it
2629 // is a sloppy mode method. 2629 // is a sloppy mode method.
2630 __ Push(isolate()->factory()->undefined_value()); 2630 __ Push(isolate()->factory()->undefined_value());
2631 } else { 2631 } else {
2632 // Load the function from the receiver. 2632 // Load the function from the receiver.
2633 ASSERT(callee->IsProperty()); 2633 DCHECK(callee->IsProperty());
2634 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); 2634 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
2635 EmitNamedPropertyLoad(callee->AsProperty()); 2635 EmitNamedPropertyLoad(callee->AsProperty());
2636 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2636 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2637 // Push the target function under the receiver. 2637 // Push the target function under the receiver.
2638 __ lw(at, MemOperand(sp, 0)); 2638 __ lw(at, MemOperand(sp, 0));
2639 __ push(at); 2639 __ push(at);
2640 __ sw(v0, MemOperand(sp, kPointerSize)); 2640 __ sw(v0, MemOperand(sp, kPointerSize));
2641 } 2641 }
2642 2642
2643 EmitCall(expr, call_type); 2643 EmitCall(expr, call_type);
2644 } 2644 }
2645 2645
2646 2646
2647 // Code common for calls using the IC. 2647 // Code common for calls using the IC.
2648 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2648 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2649 Expression* key) { 2649 Expression* key) {
2650 // Load the key. 2650 // Load the key.
2651 VisitForAccumulatorValue(key); 2651 VisitForAccumulatorValue(key);
2652 2652
2653 Expression* callee = expr->expression(); 2653 Expression* callee = expr->expression();
2654 2654
2655 // Load the function from the receiver. 2655 // Load the function from the receiver.
2656 ASSERT(callee->IsProperty()); 2656 DCHECK(callee->IsProperty());
2657 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); 2657 __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
2658 __ Move(LoadIC::NameRegister(), v0); 2658 __ Move(LoadIC::NameRegister(), v0);
2659 EmitKeyedPropertyLoad(callee->AsProperty()); 2659 EmitKeyedPropertyLoad(callee->AsProperty());
2660 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2660 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2661 2661
2662 // Push the target function under the receiver. 2662 // Push the target function under the receiver.
2663 __ lw(at, MemOperand(sp, 0)); 2663 __ lw(at, MemOperand(sp, 0));
2664 __ push(at); 2664 __ push(at);
2665 __ sw(v0, MemOperand(sp, kPointerSize)); 2665 __ sw(v0, MemOperand(sp, kPointerSize));
2666 2666
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2777 2777
2778 { PreservePositionScope scope(masm()->positions_recorder()); 2778 { PreservePositionScope scope(masm()->positions_recorder());
2779 // Generate code for loading from variables potentially shadowed 2779 // Generate code for loading from variables potentially shadowed
2780 // by eval-introduced variables. 2780 // by eval-introduced variables.
2781 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); 2781 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
2782 } 2782 }
2783 2783
2784 __ bind(&slow); 2784 __ bind(&slow);
2785 // Call the runtime to find the function to call (returned in v0) 2785 // Call the runtime to find the function to call (returned in v0)
2786 // and the object holding it (returned in v1). 2786 // and the object holding it (returned in v1).
2787 ASSERT(!context_register().is(a2)); 2787 DCHECK(!context_register().is(a2));
2788 __ li(a2, Operand(proxy->name())); 2788 __ li(a2, Operand(proxy->name()));
2789 __ Push(context_register(), a2); 2789 __ Push(context_register(), a2);
2790 __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2790 __ CallRuntime(Runtime::kLoadLookupSlot, 2);
2791 __ Push(v0, v1); // Function, receiver. 2791 __ Push(v0, v1); // Function, receiver.
2792 2792
2793 // If fast case code has been generated, emit code to push the 2793 // If fast case code has been generated, emit code to push the
2794 // function and receiver and have the slow path jump around this 2794 // function and receiver and have the slow path jump around this
2795 // code. 2795 // code.
2796 if (done.is_linked()) { 2796 if (done.is_linked()) {
2797 Label call; 2797 Label call;
(...skipping 15 matching lines...) Expand all
2813 Property* property = callee->AsProperty(); 2813 Property* property = callee->AsProperty();
2814 { PreservePositionScope scope(masm()->positions_recorder()); 2814 { PreservePositionScope scope(masm()->positions_recorder());
2815 VisitForStackValue(property->obj()); 2815 VisitForStackValue(property->obj());
2816 } 2816 }
2817 if (property->key()->IsPropertyName()) { 2817 if (property->key()->IsPropertyName()) {
2818 EmitCallWithLoadIC(expr); 2818 EmitCallWithLoadIC(expr);
2819 } else { 2819 } else {
2820 EmitKeyedCallWithLoadIC(expr, property->key()); 2820 EmitKeyedCallWithLoadIC(expr, property->key());
2821 } 2821 }
2822 } else { 2822 } else {
2823 ASSERT(call_type == Call::OTHER_CALL); 2823 DCHECK(call_type == Call::OTHER_CALL);
2824 // Call to an arbitrary expression not handled specially above. 2824 // Call to an arbitrary expression not handled specially above.
2825 { PreservePositionScope scope(masm()->positions_recorder()); 2825 { PreservePositionScope scope(masm()->positions_recorder());
2826 VisitForStackValue(callee); 2826 VisitForStackValue(callee);
2827 } 2827 }
2828 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2828 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
2829 __ push(a1); 2829 __ push(a1);
2830 // Emit function call. 2830 // Emit function call.
2831 EmitCall(expr); 2831 EmitCall(expr);
2832 } 2832 }
2833 2833
2834 #ifdef DEBUG 2834 #ifdef DEBUG
2835 // RecordJSReturnSite should have been called. 2835 // RecordJSReturnSite should have been called.
2836 ASSERT(expr->return_is_recorded_); 2836 DCHECK(expr->return_is_recorded_);
2837 #endif 2837 #endif
2838 } 2838 }
2839 2839
2840 2840
2841 void FullCodeGenerator::VisitCallNew(CallNew* expr) { 2841 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2842 Comment cmnt(masm_, "[ CallNew"); 2842 Comment cmnt(masm_, "[ CallNew");
2843 // According to ECMA-262, section 11.2.2, page 44, the function 2843 // According to ECMA-262, section 11.2.2, page 44, the function
2844 // expression in new calls must be evaluated before the 2844 // expression in new calls must be evaluated before the
2845 // arguments. 2845 // arguments.
2846 2846
(...skipping 13 matching lines...) Expand all
2860 // constructor invocation. 2860 // constructor invocation.
2861 SetSourcePosition(expr->position()); 2861 SetSourcePosition(expr->position());
2862 2862
2863 // Load function and argument count into a1 and a0. 2863 // Load function and argument count into a1 and a0.
2864 __ li(a0, Operand(arg_count)); 2864 __ li(a0, Operand(arg_count));
2865 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2865 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2866 2866
2867 // Record call targets in unoptimized code. 2867 // Record call targets in unoptimized code.
2868 if (FLAG_pretenuring_call_new) { 2868 if (FLAG_pretenuring_call_new) {
2869 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 2869 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
2870 ASSERT(expr->AllocationSiteFeedbackSlot() == 2870 DCHECK(expr->AllocationSiteFeedbackSlot() ==
2871 expr->CallNewFeedbackSlot() + 1); 2871 expr->CallNewFeedbackSlot() + 1);
2872 } 2872 }
2873 2873
2874 __ li(a2, FeedbackVector()); 2874 __ li(a2, FeedbackVector());
2875 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2875 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2876 2876
2877 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); 2877 CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
2878 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 2878 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
2879 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2879 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2880 context()->Plug(v0); 2880 context()->Plug(v0);
2881 } 2881 }
2882 2882
2883 2883
2884 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2884 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2885 ZoneList<Expression*>* args = expr->arguments(); 2885 ZoneList<Expression*>* args = expr->arguments();
2886 ASSERT(args->length() == 1); 2886 DCHECK(args->length() == 1);
2887 2887
2888 VisitForAccumulatorValue(args->at(0)); 2888 VisitForAccumulatorValue(args->at(0));
2889 2889
2890 Label materialize_true, materialize_false; 2890 Label materialize_true, materialize_false;
2891 Label* if_true = NULL; 2891 Label* if_true = NULL;
2892 Label* if_false = NULL; 2892 Label* if_false = NULL;
2893 Label* fall_through = NULL; 2893 Label* fall_through = NULL;
2894 context()->PrepareTest(&materialize_true, &materialize_false, 2894 context()->PrepareTest(&materialize_true, &materialize_false,
2895 &if_true, &if_false, &fall_through); 2895 &if_true, &if_false, &fall_through);
2896 2896
2897 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2897 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2898 __ SmiTst(v0, t0); 2898 __ SmiTst(v0, t0);
2899 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); 2899 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through);
2900 2900
2901 context()->Plug(if_true, if_false); 2901 context()->Plug(if_true, if_false);
2902 } 2902 }
2903 2903
2904 2904
2905 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { 2905 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
2906 ZoneList<Expression*>* args = expr->arguments(); 2906 ZoneList<Expression*>* args = expr->arguments();
2907 ASSERT(args->length() == 1); 2907 DCHECK(args->length() == 1);
2908 2908
2909 VisitForAccumulatorValue(args->at(0)); 2909 VisitForAccumulatorValue(args->at(0));
2910 2910
2911 Label materialize_true, materialize_false; 2911 Label materialize_true, materialize_false;
2912 Label* if_true = NULL; 2912 Label* if_true = NULL;
2913 Label* if_false = NULL; 2913 Label* if_false = NULL;
2914 Label* fall_through = NULL; 2914 Label* fall_through = NULL;
2915 context()->PrepareTest(&materialize_true, &materialize_false, 2915 context()->PrepareTest(&materialize_true, &materialize_false,
2916 &if_true, &if_false, &fall_through); 2916 &if_true, &if_false, &fall_through);
2917 2917
2918 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2918 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2919 __ NonNegativeSmiTst(v0, at); 2919 __ NonNegativeSmiTst(v0, at);
2920 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); 2920 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through);
2921 2921
2922 context()->Plug(if_true, if_false); 2922 context()->Plug(if_true, if_false);
2923 } 2923 }
2924 2924
2925 2925
2926 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { 2926 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
2927 ZoneList<Expression*>* args = expr->arguments(); 2927 ZoneList<Expression*>* args = expr->arguments();
2928 ASSERT(args->length() == 1); 2928 DCHECK(args->length() == 1);
2929 2929
2930 VisitForAccumulatorValue(args->at(0)); 2930 VisitForAccumulatorValue(args->at(0));
2931 2931
2932 Label materialize_true, materialize_false; 2932 Label materialize_true, materialize_false;
2933 Label* if_true = NULL; 2933 Label* if_true = NULL;
2934 Label* if_false = NULL; 2934 Label* if_false = NULL;
2935 Label* fall_through = NULL; 2935 Label* fall_through = NULL;
2936 context()->PrepareTest(&materialize_true, &materialize_false, 2936 context()->PrepareTest(&materialize_true, &materialize_false,
2937 &if_true, &if_false, &fall_through); 2937 &if_true, &if_false, &fall_through);
2938 2938
(...skipping 10 matching lines...) Expand all
2949 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2949 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2950 Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE), 2950 Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE),
2951 if_true, if_false, fall_through); 2951 if_true, if_false, fall_through);
2952 2952
2953 context()->Plug(if_true, if_false); 2953 context()->Plug(if_true, if_false);
2954 } 2954 }
2955 2955
2956 2956
2957 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { 2957 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
2958 ZoneList<Expression*>* args = expr->arguments(); 2958 ZoneList<Expression*>* args = expr->arguments();
2959 ASSERT(args->length() == 1); 2959 DCHECK(args->length() == 1);
2960 2960
2961 VisitForAccumulatorValue(args->at(0)); 2961 VisitForAccumulatorValue(args->at(0));
2962 2962
2963 Label materialize_true, materialize_false; 2963 Label materialize_true, materialize_false;
2964 Label* if_true = NULL; 2964 Label* if_true = NULL;
2965 Label* if_false = NULL; 2965 Label* if_false = NULL;
2966 Label* fall_through = NULL; 2966 Label* fall_through = NULL;
2967 context()->PrepareTest(&materialize_true, &materialize_false, 2967 context()->PrepareTest(&materialize_true, &materialize_false,
2968 &if_true, &if_false, &fall_through); 2968 &if_true, &if_false, &fall_through);
2969 2969
2970 __ JumpIfSmi(v0, if_false); 2970 __ JumpIfSmi(v0, if_false);
2971 __ GetObjectType(v0, a1, a1); 2971 __ GetObjectType(v0, a1, a1);
2972 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2972 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2973 Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE), 2973 Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE),
2974 if_true, if_false, fall_through); 2974 if_true, if_false, fall_through);
2975 2975
2976 context()->Plug(if_true, if_false); 2976 context()->Plug(if_true, if_false);
2977 } 2977 }
2978 2978
2979 2979
2980 void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) { 2980 void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) {
2981 ZoneList<Expression*>* args = expr->arguments(); 2981 ZoneList<Expression*>* args = expr->arguments();
2982 ASSERT(args->length() == 1); 2982 DCHECK(args->length() == 1);
2983 2983
2984 VisitForAccumulatorValue(args->at(0)); 2984 VisitForAccumulatorValue(args->at(0));
2985 2985
2986 Label materialize_true, materialize_false; 2986 Label materialize_true, materialize_false;
2987 Label* if_true = NULL; 2987 Label* if_true = NULL;
2988 Label* if_false = NULL; 2988 Label* if_false = NULL;
2989 Label* fall_through = NULL; 2989 Label* fall_through = NULL;
2990 context()->PrepareTest(&materialize_true, &materialize_false, 2990 context()->PrepareTest(&materialize_true, &materialize_false,
2991 &if_true, &if_false, &fall_through); 2991 &if_true, &if_false, &fall_through);
2992 2992
2993 __ JumpIfSmi(v0, if_false); 2993 __ JumpIfSmi(v0, if_false);
2994 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 2994 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
2995 __ lbu(a1, FieldMemOperand(a1, Map::kBitFieldOffset)); 2995 __ lbu(a1, FieldMemOperand(a1, Map::kBitFieldOffset));
2996 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2996 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2997 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); 2997 __ And(at, a1, Operand(1 << Map::kIsUndetectable));
2998 Split(ne, at, Operand(zero_reg), if_true, if_false, fall_through); 2998 Split(ne, at, Operand(zero_reg), if_true, if_false, fall_through);
2999 2999
3000 context()->Plug(if_true, if_false); 3000 context()->Plug(if_true, if_false);
3001 } 3001 }
3002 3002
3003 3003
3004 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( 3004 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
3005 CallRuntime* expr) { 3005 CallRuntime* expr) {
3006 ZoneList<Expression*>* args = expr->arguments(); 3006 ZoneList<Expression*>* args = expr->arguments();
3007 ASSERT(args->length() == 1); 3007 DCHECK(args->length() == 1);
3008 3008
3009 VisitForAccumulatorValue(args->at(0)); 3009 VisitForAccumulatorValue(args->at(0));
3010 3010
3011 Label materialize_true, materialize_false, skip_lookup; 3011 Label materialize_true, materialize_false, skip_lookup;
3012 Label* if_true = NULL; 3012 Label* if_true = NULL;
3013 Label* if_false = NULL; 3013 Label* if_false = NULL;
3014 Label* fall_through = NULL; 3014 Label* fall_through = NULL;
3015 context()->PrepareTest(&materialize_true, &materialize_false, 3015 context()->PrepareTest(&materialize_true, &materialize_false,
3016 &if_true, &if_false, &fall_through); 3016 &if_true, &if_false, &fall_through);
3017 3017
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3084 __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); 3084 __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
3085 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3085 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3086 Split(eq, a2, Operand(a3), if_true, if_false, fall_through); 3086 Split(eq, a2, Operand(a3), if_true, if_false, fall_through);
3087 3087
3088 context()->Plug(if_true, if_false); 3088 context()->Plug(if_true, if_false);
3089 } 3089 }
3090 3090
3091 3091
3092 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { 3092 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
3093 ZoneList<Expression*>* args = expr->arguments(); 3093 ZoneList<Expression*>* args = expr->arguments();
3094 ASSERT(args->length() == 1); 3094 DCHECK(args->length() == 1);
3095 3095
3096 VisitForAccumulatorValue(args->at(0)); 3096 VisitForAccumulatorValue(args->at(0));
3097 3097
3098 Label materialize_true, materialize_false; 3098 Label materialize_true, materialize_false;
3099 Label* if_true = NULL; 3099 Label* if_true = NULL;
3100 Label* if_false = NULL; 3100 Label* if_false = NULL;
3101 Label* fall_through = NULL; 3101 Label* fall_through = NULL;
3102 context()->PrepareTest(&materialize_true, &materialize_false, 3102 context()->PrepareTest(&materialize_true, &materialize_false,
3103 &if_true, &if_false, &fall_through); 3103 &if_true, &if_false, &fall_through);
3104 3104
3105 __ JumpIfSmi(v0, if_false); 3105 __ JumpIfSmi(v0, if_false);
3106 __ GetObjectType(v0, a1, a2); 3106 __ GetObjectType(v0, a1, a2);
3107 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3107 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3108 __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE)); 3108 __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE));
3109 __ Branch(if_false); 3109 __ Branch(if_false);
3110 3110
3111 context()->Plug(if_true, if_false); 3111 context()->Plug(if_true, if_false);
3112 } 3112 }
3113 3113
3114 3114
3115 void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) { 3115 void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
3116 ZoneList<Expression*>* args = expr->arguments(); 3116 ZoneList<Expression*>* args = expr->arguments();
3117 ASSERT(args->length() == 1); 3117 DCHECK(args->length() == 1);
3118 3118
3119 VisitForAccumulatorValue(args->at(0)); 3119 VisitForAccumulatorValue(args->at(0));
3120 3120
3121 Label materialize_true, materialize_false; 3121 Label materialize_true, materialize_false;
3122 Label* if_true = NULL; 3122 Label* if_true = NULL;
3123 Label* if_false = NULL; 3123 Label* if_false = NULL;
3124 Label* fall_through = NULL; 3124 Label* fall_through = NULL;
3125 context()->PrepareTest(&materialize_true, &materialize_false, 3125 context()->PrepareTest(&materialize_true, &materialize_false,
3126 &if_true, &if_false, &fall_through); 3126 &if_true, &if_false, &fall_through);
3127 3127
3128 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK); 3128 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
3129 __ lw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 3129 __ lw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
3130 __ lw(a1, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 3130 __ lw(a1, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
3131 __ li(t0, 0x80000000); 3131 __ li(t0, 0x80000000);
3132 Label not_nan; 3132 Label not_nan;
3133 __ Branch(&not_nan, ne, a2, Operand(t0)); 3133 __ Branch(&not_nan, ne, a2, Operand(t0));
3134 __ mov(t0, zero_reg); 3134 __ mov(t0, zero_reg);
3135 __ mov(a2, a1); 3135 __ mov(a2, a1);
3136 __ bind(&not_nan); 3136 __ bind(&not_nan);
3137 3137
3138 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3138 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3139 Split(eq, a2, Operand(t0), if_true, if_false, fall_through); 3139 Split(eq, a2, Operand(t0), if_true, if_false, fall_through);
3140 3140
3141 context()->Plug(if_true, if_false); 3141 context()->Plug(if_true, if_false);
3142 } 3142 }
3143 3143
3144 3144
3145 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { 3145 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
3146 ZoneList<Expression*>* args = expr->arguments(); 3146 ZoneList<Expression*>* args = expr->arguments();
3147 ASSERT(args->length() == 1); 3147 DCHECK(args->length() == 1);
3148 3148
3149 VisitForAccumulatorValue(args->at(0)); 3149 VisitForAccumulatorValue(args->at(0));
3150 3150
3151 Label materialize_true, materialize_false; 3151 Label materialize_true, materialize_false;
3152 Label* if_true = NULL; 3152 Label* if_true = NULL;
3153 Label* if_false = NULL; 3153 Label* if_false = NULL;
3154 Label* fall_through = NULL; 3154 Label* fall_through = NULL;
3155 context()->PrepareTest(&materialize_true, &materialize_false, 3155 context()->PrepareTest(&materialize_true, &materialize_false,
3156 &if_true, &if_false, &fall_through); 3156 &if_true, &if_false, &fall_through);
3157 3157
3158 __ JumpIfSmi(v0, if_false); 3158 __ JumpIfSmi(v0, if_false);
3159 __ GetObjectType(v0, a1, a1); 3159 __ GetObjectType(v0, a1, a1);
3160 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3160 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3161 Split(eq, a1, Operand(JS_ARRAY_TYPE), 3161 Split(eq, a1, Operand(JS_ARRAY_TYPE),
3162 if_true, if_false, fall_through); 3162 if_true, if_false, fall_through);
3163 3163
3164 context()->Plug(if_true, if_false); 3164 context()->Plug(if_true, if_false);
3165 } 3165 }
3166 3166
3167 3167
3168 void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) { 3168 void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
3169 ZoneList<Expression*>* args = expr->arguments(); 3169 ZoneList<Expression*>* args = expr->arguments();
3170 ASSERT(args->length() == 1); 3170 DCHECK(args->length() == 1);
3171 3171
3172 VisitForAccumulatorValue(args->at(0)); 3172 VisitForAccumulatorValue(args->at(0));
3173 3173
3174 Label materialize_true, materialize_false; 3174 Label materialize_true, materialize_false;
3175 Label* if_true = NULL; 3175 Label* if_true = NULL;
3176 Label* if_false = NULL; 3176 Label* if_false = NULL;
3177 Label* fall_through = NULL; 3177 Label* fall_through = NULL;
3178 context()->PrepareTest(&materialize_true, &materialize_false, 3178 context()->PrepareTest(&materialize_true, &materialize_false,
3179 &if_true, &if_false, &fall_through); 3179 &if_true, &if_false, &fall_through);
3180 3180
3181 __ JumpIfSmi(v0, if_false); 3181 __ JumpIfSmi(v0, if_false);
3182 __ GetObjectType(v0, a1, a1); 3182 __ GetObjectType(v0, a1, a1);
3183 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3183 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3184 Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through); 3184 Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through);
3185 3185
3186 context()->Plug(if_true, if_false); 3186 context()->Plug(if_true, if_false);
3187 } 3187 }
3188 3188
3189 3189
3190 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) { 3190 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
3191 ASSERT(expr->arguments()->length() == 0); 3191 DCHECK(expr->arguments()->length() == 0);
3192 3192
3193 Label materialize_true, materialize_false; 3193 Label materialize_true, materialize_false;
3194 Label* if_true = NULL; 3194 Label* if_true = NULL;
3195 Label* if_false = NULL; 3195 Label* if_false = NULL;
3196 Label* fall_through = NULL; 3196 Label* fall_through = NULL;
3197 context()->PrepareTest(&materialize_true, &materialize_false, 3197 context()->PrepareTest(&materialize_true, &materialize_false,
3198 &if_true, &if_false, &fall_through); 3198 &if_true, &if_false, &fall_through);
3199 3199
3200 // Get the frame pointer for the calling frame. 3200 // Get the frame pointer for the calling frame.
3201 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3201 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
(...skipping 11 matching lines...) Expand all
3213 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3213 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3214 Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)), 3214 Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)),
3215 if_true, if_false, fall_through); 3215 if_true, if_false, fall_through);
3216 3216
3217 context()->Plug(if_true, if_false); 3217 context()->Plug(if_true, if_false);
3218 } 3218 }
3219 3219
3220 3220
3221 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { 3221 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
3222 ZoneList<Expression*>* args = expr->arguments(); 3222 ZoneList<Expression*>* args = expr->arguments();
3223 ASSERT(args->length() == 2); 3223 DCHECK(args->length() == 2);
3224 3224
3225 // Load the two objects into registers and perform the comparison. 3225 // Load the two objects into registers and perform the comparison.
3226 VisitForStackValue(args->at(0)); 3226 VisitForStackValue(args->at(0));
3227 VisitForAccumulatorValue(args->at(1)); 3227 VisitForAccumulatorValue(args->at(1));
3228 3228
3229 Label materialize_true, materialize_false; 3229 Label materialize_true, materialize_false;
3230 Label* if_true = NULL; 3230 Label* if_true = NULL;
3231 Label* if_false = NULL; 3231 Label* if_false = NULL;
3232 Label* fall_through = NULL; 3232 Label* fall_through = NULL;
3233 context()->PrepareTest(&materialize_true, &materialize_false, 3233 context()->PrepareTest(&materialize_true, &materialize_false,
3234 &if_true, &if_false, &fall_through); 3234 &if_true, &if_false, &fall_through);
3235 3235
3236 __ pop(a1); 3236 __ pop(a1);
3237 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3237 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3238 Split(eq, v0, Operand(a1), if_true, if_false, fall_through); 3238 Split(eq, v0, Operand(a1), if_true, if_false, fall_through);
3239 3239
3240 context()->Plug(if_true, if_false); 3240 context()->Plug(if_true, if_false);
3241 } 3241 }
3242 3242
3243 3243
3244 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { 3244 void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
3245 ZoneList<Expression*>* args = expr->arguments(); 3245 ZoneList<Expression*>* args = expr->arguments();
3246 ASSERT(args->length() == 1); 3246 DCHECK(args->length() == 1);
3247 3247
3248 // ArgumentsAccessStub expects the key in a1 and the formal 3248 // ArgumentsAccessStub expects the key in a1 and the formal
3249 // parameter count in a0. 3249 // parameter count in a0.
3250 VisitForAccumulatorValue(args->at(0)); 3250 VisitForAccumulatorValue(args->at(0));
3251 __ mov(a1, v0); 3251 __ mov(a1, v0);
3252 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); 3252 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
3253 ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); 3253 ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
3254 __ CallStub(&stub); 3254 __ CallStub(&stub);
3255 context()->Plug(v0); 3255 context()->Plug(v0);
3256 } 3256 }
3257 3257
3258 3258
3259 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { 3259 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
3260 ASSERT(expr->arguments()->length() == 0); 3260 DCHECK(expr->arguments()->length() == 0);
3261 Label exit; 3261 Label exit;
3262 // Get the number of formal parameters. 3262 // Get the number of formal parameters.
3263 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); 3263 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
3264 3264
3265 // Check if the calling frame is an arguments adaptor frame. 3265 // Check if the calling frame is an arguments adaptor frame.
3266 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 3266 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3267 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset)); 3267 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset));
3268 __ Branch(&exit, ne, a3, 3268 __ Branch(&exit, ne, a3,
3269 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3269 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3270 3270
3271 // Arguments adaptor case: Read the arguments length from the 3271 // Arguments adaptor case: Read the arguments length from the
3272 // adaptor frame. 3272 // adaptor frame.
3273 __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3273 __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3274 3274
3275 __ bind(&exit); 3275 __ bind(&exit);
3276 context()->Plug(v0); 3276 context()->Plug(v0);
3277 } 3277 }
3278 3278
3279 3279
3280 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { 3280 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
3281 ZoneList<Expression*>* args = expr->arguments(); 3281 ZoneList<Expression*>* args = expr->arguments();
3282 ASSERT(args->length() == 1); 3282 DCHECK(args->length() == 1);
3283 Label done, null, function, non_function_constructor; 3283 Label done, null, function, non_function_constructor;
3284 3284
3285 VisitForAccumulatorValue(args->at(0)); 3285 VisitForAccumulatorValue(args->at(0));
3286 3286
3287 // If the object is a smi, we return null. 3287 // If the object is a smi, we return null.
3288 __ JumpIfSmi(v0, &null); 3288 __ JumpIfSmi(v0, &null);
3289 3289
3290 // Check that the object is a JS object but take special care of JS 3290 // Check that the object is a JS object but take special care of JS
3291 // functions to make sure they have 'Function' as their class. 3291 // functions to make sure they have 'Function' as their class.
3292 // Assume that there are only two callable types, and one of them is at 3292 // Assume that there are only two callable types, and one of them is at
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3334 __ bind(&done); 3334 __ bind(&done);
3335 3335
3336 context()->Plug(v0); 3336 context()->Plug(v0);
3337 } 3337 }
3338 3338
3339 3339
3340 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { 3340 void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
3341 // Load the arguments on the stack and call the stub. 3341 // Load the arguments on the stack and call the stub.
3342 SubStringStub stub(isolate()); 3342 SubStringStub stub(isolate());
3343 ZoneList<Expression*>* args = expr->arguments(); 3343 ZoneList<Expression*>* args = expr->arguments();
3344 ASSERT(args->length() == 3); 3344 DCHECK(args->length() == 3);
3345 VisitForStackValue(args->at(0)); 3345 VisitForStackValue(args->at(0));
3346 VisitForStackValue(args->at(1)); 3346 VisitForStackValue(args->at(1));
3347 VisitForStackValue(args->at(2)); 3347 VisitForStackValue(args->at(2));
3348 __ CallStub(&stub); 3348 __ CallStub(&stub);
3349 context()->Plug(v0); 3349 context()->Plug(v0);
3350 } 3350 }
3351 3351
3352 3352
3353 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { 3353 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
3354 // Load the arguments on the stack and call the stub. 3354 // Load the arguments on the stack and call the stub.
3355 RegExpExecStub stub(isolate()); 3355 RegExpExecStub stub(isolate());
3356 ZoneList<Expression*>* args = expr->arguments(); 3356 ZoneList<Expression*>* args = expr->arguments();
3357 ASSERT(args->length() == 4); 3357 DCHECK(args->length() == 4);
3358 VisitForStackValue(args->at(0)); 3358 VisitForStackValue(args->at(0));
3359 VisitForStackValue(args->at(1)); 3359 VisitForStackValue(args->at(1));
3360 VisitForStackValue(args->at(2)); 3360 VisitForStackValue(args->at(2));
3361 VisitForStackValue(args->at(3)); 3361 VisitForStackValue(args->at(3));
3362 __ CallStub(&stub); 3362 __ CallStub(&stub);
3363 context()->Plug(v0); 3363 context()->Plug(v0);
3364 } 3364 }
3365 3365
3366 3366
3367 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { 3367 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
3368 ZoneList<Expression*>* args = expr->arguments(); 3368 ZoneList<Expression*>* args = expr->arguments();
3369 ASSERT(args->length() == 1); 3369 DCHECK(args->length() == 1);
3370 3370
3371 VisitForAccumulatorValue(args->at(0)); // Load the object. 3371 VisitForAccumulatorValue(args->at(0)); // Load the object.
3372 3372
3373 Label done; 3373 Label done;
3374 // If the object is a smi return the object. 3374 // If the object is a smi return the object.
3375 __ JumpIfSmi(v0, &done); 3375 __ JumpIfSmi(v0, &done);
3376 // If the object is not a value type, return the object. 3376 // If the object is not a value type, return the object.
3377 __ GetObjectType(v0, a1, a1); 3377 __ GetObjectType(v0, a1, a1);
3378 __ Branch(&done, ne, a1, Operand(JS_VALUE_TYPE)); 3378 __ Branch(&done, ne, a1, Operand(JS_VALUE_TYPE));
3379 3379
3380 __ lw(v0, FieldMemOperand(v0, JSValue::kValueOffset)); 3380 __ lw(v0, FieldMemOperand(v0, JSValue::kValueOffset));
3381 3381
3382 __ bind(&done); 3382 __ bind(&done);
3383 context()->Plug(v0); 3383 context()->Plug(v0);
3384 } 3384 }
3385 3385
3386 3386
3387 void FullCodeGenerator::EmitDateField(CallRuntime* expr) { 3387 void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
3388 ZoneList<Expression*>* args = expr->arguments(); 3388 ZoneList<Expression*>* args = expr->arguments();
3389 ASSERT(args->length() == 2); 3389 DCHECK(args->length() == 2);
3390 ASSERT_NE(NULL, args->at(1)->AsLiteral()); 3390 DCHECK_NE(NULL, args->at(1)->AsLiteral());
3391 Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value())); 3391 Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
3392 3392
3393 VisitForAccumulatorValue(args->at(0)); // Load the object. 3393 VisitForAccumulatorValue(args->at(0)); // Load the object.
3394 3394
3395 Label runtime, done, not_date_object; 3395 Label runtime, done, not_date_object;
3396 Register object = v0; 3396 Register object = v0;
3397 Register result = v0; 3397 Register result = v0;
3398 Register scratch0 = t5; 3398 Register scratch0 = t5;
3399 Register scratch1 = a1; 3399 Register scratch1 = a1;
3400 3400
(...skipping 25 matching lines...) Expand all
3426 3426
3427 __ bind(&not_date_object); 3427 __ bind(&not_date_object);
3428 __ CallRuntime(Runtime::kThrowNotDateError, 0); 3428 __ CallRuntime(Runtime::kThrowNotDateError, 0);
3429 __ bind(&done); 3429 __ bind(&done);
3430 context()->Plug(v0); 3430 context()->Plug(v0);
3431 } 3431 }
3432 3432
3433 3433
3434 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3434 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3435 ZoneList<Expression*>* args = expr->arguments(); 3435 ZoneList<Expression*>* args = expr->arguments();
3436 ASSERT_EQ(3, args->length()); 3436 DCHECK_EQ(3, args->length());
3437 3437
3438 Register string = v0; 3438 Register string = v0;
3439 Register index = a1; 3439 Register index = a1;
3440 Register value = a2; 3440 Register value = a2;
3441 3441
3442 VisitForStackValue(args->at(1)); // index 3442 VisitForStackValue(args->at(1)); // index
3443 VisitForStackValue(args->at(2)); // value 3443 VisitForStackValue(args->at(2)); // value
3444 VisitForAccumulatorValue(args->at(0)); // string 3444 VisitForAccumulatorValue(args->at(0)); // string
3445 __ Pop(index, value); 3445 __ Pop(index, value);
3446 3446
(...skipping 16 matching lines...) Expand all
3463 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3463 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3464 __ SmiUntag(index); 3464 __ SmiUntag(index);
3465 __ Addu(at, at, index); 3465 __ Addu(at, at, index);
3466 __ sb(value, MemOperand(at)); 3466 __ sb(value, MemOperand(at));
3467 context()->Plug(string); 3467 context()->Plug(string);
3468 } 3468 }
3469 3469
3470 3470
3471 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 3471 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3472 ZoneList<Expression*>* args = expr->arguments(); 3472 ZoneList<Expression*>* args = expr->arguments();
3473 ASSERT_EQ(3, args->length()); 3473 DCHECK_EQ(3, args->length());
3474 3474
3475 Register string = v0; 3475 Register string = v0;
3476 Register index = a1; 3476 Register index = a1;
3477 Register value = a2; 3477 Register value = a2;
3478 3478
3479 VisitForStackValue(args->at(1)); // index 3479 VisitForStackValue(args->at(1)); // index
3480 VisitForStackValue(args->at(2)); // value 3480 VisitForStackValue(args->at(2)); // value
3481 VisitForAccumulatorValue(args->at(0)); // string 3481 VisitForAccumulatorValue(args->at(0)); // string
3482 __ Pop(index, value); 3482 __ Pop(index, value);
3483 3483
(...skipping 17 matching lines...) Expand all
3501 __ Addu(at, at, index); 3501 __ Addu(at, at, index);
3502 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 3502 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
3503 __ sh(value, MemOperand(at)); 3503 __ sh(value, MemOperand(at));
3504 context()->Plug(string); 3504 context()->Plug(string);
3505 } 3505 }
3506 3506
3507 3507
3508 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { 3508 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
3509 // Load the arguments on the stack and call the runtime function. 3509 // Load the arguments on the stack and call the runtime function.
3510 ZoneList<Expression*>* args = expr->arguments(); 3510 ZoneList<Expression*>* args = expr->arguments();
3511 ASSERT(args->length() == 2); 3511 DCHECK(args->length() == 2);
3512 VisitForStackValue(args->at(0)); 3512 VisitForStackValue(args->at(0));
3513 VisitForStackValue(args->at(1)); 3513 VisitForStackValue(args->at(1));
3514 MathPowStub stub(isolate(), MathPowStub::ON_STACK); 3514 MathPowStub stub(isolate(), MathPowStub::ON_STACK);
3515 __ CallStub(&stub); 3515 __ CallStub(&stub);
3516 context()->Plug(v0); 3516 context()->Plug(v0);
3517 } 3517 }
3518 3518
3519 3519
3520 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { 3520 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
3521 ZoneList<Expression*>* args = expr->arguments(); 3521 ZoneList<Expression*>* args = expr->arguments();
3522 ASSERT(args->length() == 2); 3522 DCHECK(args->length() == 2);
3523 3523
3524 VisitForStackValue(args->at(0)); // Load the object. 3524 VisitForStackValue(args->at(0)); // Load the object.
3525 VisitForAccumulatorValue(args->at(1)); // Load the value. 3525 VisitForAccumulatorValue(args->at(1)); // Load the value.
3526 __ pop(a1); // v0 = value. a1 = object. 3526 __ pop(a1); // v0 = value. a1 = object.
3527 3527
3528 Label done; 3528 Label done;
3529 // If the object is a smi, return the value. 3529 // If the object is a smi, return the value.
3530 __ JumpIfSmi(a1, &done); 3530 __ JumpIfSmi(a1, &done);
3531 3531
3532 // If the object is not a value type, return the value. 3532 // If the object is not a value type, return the value.
3533 __ GetObjectType(a1, a2, a2); 3533 __ GetObjectType(a1, a2, a2);
3534 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); 3534 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE));
3535 3535
3536 // Store the value. 3536 // Store the value.
3537 __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset)); 3537 __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset));
3538 // Update the write barrier. Save the value as it will be 3538 // Update the write barrier. Save the value as it will be
3539 // overwritten by the write barrier code and is needed afterward. 3539 // overwritten by the write barrier code and is needed afterward.
3540 __ mov(a2, v0); 3540 __ mov(a2, v0);
3541 __ RecordWriteField( 3541 __ RecordWriteField(
3542 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); 3542 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs);
3543 3543
3544 __ bind(&done); 3544 __ bind(&done);
3545 context()->Plug(v0); 3545 context()->Plug(v0);
3546 } 3546 }
3547 3547
3548 3548
3549 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { 3549 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
3550 ZoneList<Expression*>* args = expr->arguments(); 3550 ZoneList<Expression*>* args = expr->arguments();
3551 ASSERT_EQ(args->length(), 1); 3551 DCHECK_EQ(args->length(), 1);
3552 3552
3553 // Load the argument into a0 and call the stub. 3553 // Load the argument into a0 and call the stub.
3554 VisitForAccumulatorValue(args->at(0)); 3554 VisitForAccumulatorValue(args->at(0));
3555 __ mov(a0, result_register()); 3555 __ mov(a0, result_register());
3556 3556
3557 NumberToStringStub stub(isolate()); 3557 NumberToStringStub stub(isolate());
3558 __ CallStub(&stub); 3558 __ CallStub(&stub);
3559 context()->Plug(v0); 3559 context()->Plug(v0);
3560 } 3560 }
3561 3561
3562 3562
3563 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3563 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3564 ZoneList<Expression*>* args = expr->arguments(); 3564 ZoneList<Expression*>* args = expr->arguments();
3565 ASSERT(args->length() == 1); 3565 DCHECK(args->length() == 1);
3566 3566
3567 VisitForAccumulatorValue(args->at(0)); 3567 VisitForAccumulatorValue(args->at(0));
3568 3568
3569 Label done; 3569 Label done;
3570 StringCharFromCodeGenerator generator(v0, a1); 3570 StringCharFromCodeGenerator generator(v0, a1);
3571 generator.GenerateFast(masm_); 3571 generator.GenerateFast(masm_);
3572 __ jmp(&done); 3572 __ jmp(&done);
3573 3573
3574 NopRuntimeCallHelper call_helper; 3574 NopRuntimeCallHelper call_helper;
3575 generator.GenerateSlow(masm_, call_helper); 3575 generator.GenerateSlow(masm_, call_helper);
3576 3576
3577 __ bind(&done); 3577 __ bind(&done);
3578 context()->Plug(a1); 3578 context()->Plug(a1);
3579 } 3579 }
3580 3580
3581 3581
3582 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { 3582 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
3583 ZoneList<Expression*>* args = expr->arguments(); 3583 ZoneList<Expression*>* args = expr->arguments();
3584 ASSERT(args->length() == 2); 3584 DCHECK(args->length() == 2);
3585 3585
3586 VisitForStackValue(args->at(0)); 3586 VisitForStackValue(args->at(0));
3587 VisitForAccumulatorValue(args->at(1)); 3587 VisitForAccumulatorValue(args->at(1));
3588 __ mov(a0, result_register()); 3588 __ mov(a0, result_register());
3589 3589
3590 Register object = a1; 3590 Register object = a1;
3591 Register index = a0; 3591 Register index = a0;
3592 Register result = v0; 3592 Register result = v0;
3593 3593
3594 __ pop(object); 3594 __ pop(object);
(...skipping 26 matching lines...) Expand all
3621 NopRuntimeCallHelper call_helper; 3621 NopRuntimeCallHelper call_helper;
3622 generator.GenerateSlow(masm_, call_helper); 3622 generator.GenerateSlow(masm_, call_helper);
3623 3623
3624 __ bind(&done); 3624 __ bind(&done);
3625 context()->Plug(result); 3625 context()->Plug(result);
3626 } 3626 }
3627 3627
3628 3628
3629 void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { 3629 void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
3630 ZoneList<Expression*>* args = expr->arguments(); 3630 ZoneList<Expression*>* args = expr->arguments();
3631 ASSERT(args->length() == 2); 3631 DCHECK(args->length() == 2);
3632 3632
3633 VisitForStackValue(args->at(0)); 3633 VisitForStackValue(args->at(0));
3634 VisitForAccumulatorValue(args->at(1)); 3634 VisitForAccumulatorValue(args->at(1));
3635 __ mov(a0, result_register()); 3635 __ mov(a0, result_register());
3636 3636
3637 Register object = a1; 3637 Register object = a1;
3638 Register index = a0; 3638 Register index = a0;
3639 Register scratch = a3; 3639 Register scratch = a3;
3640 Register result = v0; 3640 Register result = v0;
3641 3641
(...skipping 28 matching lines...) Expand all
3670 NopRuntimeCallHelper call_helper; 3670 NopRuntimeCallHelper call_helper;
3671 generator.GenerateSlow(masm_, call_helper); 3671 generator.GenerateSlow(masm_, call_helper);
3672 3672
3673 __ bind(&done); 3673 __ bind(&done);
3674 context()->Plug(result); 3674 context()->Plug(result);
3675 } 3675 }
3676 3676
3677 3677
3678 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { 3678 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
3679 ZoneList<Expression*>* args = expr->arguments(); 3679 ZoneList<Expression*>* args = expr->arguments();
3680 ASSERT_EQ(2, args->length()); 3680 DCHECK_EQ(2, args->length());
3681 VisitForStackValue(args->at(0)); 3681 VisitForStackValue(args->at(0));
3682 VisitForAccumulatorValue(args->at(1)); 3682 VisitForAccumulatorValue(args->at(1));
3683 3683
3684 __ pop(a1); 3684 __ pop(a1);
3685 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. 3685 __ mov(a0, result_register()); // StringAddStub requires args in a0, a1.
3686 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); 3686 StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
3687 __ CallStub(&stub); 3687 __ CallStub(&stub);
3688 context()->Plug(v0); 3688 context()->Plug(v0);
3689 } 3689 }
3690 3690
3691 3691
3692 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { 3692 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
3693 ZoneList<Expression*>* args = expr->arguments(); 3693 ZoneList<Expression*>* args = expr->arguments();
3694 ASSERT_EQ(2, args->length()); 3694 DCHECK_EQ(2, args->length());
3695 3695
3696 VisitForStackValue(args->at(0)); 3696 VisitForStackValue(args->at(0));
3697 VisitForStackValue(args->at(1)); 3697 VisitForStackValue(args->at(1));
3698 3698
3699 StringCompareStub stub(isolate()); 3699 StringCompareStub stub(isolate());
3700 __ CallStub(&stub); 3700 __ CallStub(&stub);
3701 context()->Plug(v0); 3701 context()->Plug(v0);
3702 } 3702 }
3703 3703
3704 3704
3705 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { 3705 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
3706 ZoneList<Expression*>* args = expr->arguments(); 3706 ZoneList<Expression*>* args = expr->arguments();
3707 ASSERT(args->length() >= 2); 3707 DCHECK(args->length() >= 2);
3708 3708
3709 int arg_count = args->length() - 2; // 2 ~ receiver and function. 3709 int arg_count = args->length() - 2; // 2 ~ receiver and function.
3710 for (int i = 0; i < arg_count + 1; i++) { 3710 for (int i = 0; i < arg_count + 1; i++) {
3711 VisitForStackValue(args->at(i)); 3711 VisitForStackValue(args->at(i));
3712 } 3712 }
3713 VisitForAccumulatorValue(args->last()); // Function. 3713 VisitForAccumulatorValue(args->last()); // Function.
3714 3714
3715 Label runtime, done; 3715 Label runtime, done;
3716 // Check for non-function argument (including proxy). 3716 // Check for non-function argument (including proxy).
3717 __ JumpIfSmi(v0, &runtime); 3717 __ JumpIfSmi(v0, &runtime);
(...skipping 12 matching lines...) Expand all
3730 __ CallRuntime(Runtime::kCall, args->length()); 3730 __ CallRuntime(Runtime::kCall, args->length());
3731 __ bind(&done); 3731 __ bind(&done);
3732 3732
3733 context()->Plug(v0); 3733 context()->Plug(v0);
3734 } 3734 }
3735 3735
3736 3736
3737 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { 3737 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
3738 RegExpConstructResultStub stub(isolate()); 3738 RegExpConstructResultStub stub(isolate());
3739 ZoneList<Expression*>* args = expr->arguments(); 3739 ZoneList<Expression*>* args = expr->arguments();
3740 ASSERT(args->length() == 3); 3740 DCHECK(args->length() == 3);
3741 VisitForStackValue(args->at(0)); 3741 VisitForStackValue(args->at(0));
3742 VisitForStackValue(args->at(1)); 3742 VisitForStackValue(args->at(1));
3743 VisitForAccumulatorValue(args->at(2)); 3743 VisitForAccumulatorValue(args->at(2));
3744 __ mov(a0, result_register()); 3744 __ mov(a0, result_register());
3745 __ pop(a1); 3745 __ pop(a1);
3746 __ pop(a2); 3746 __ pop(a2);
3747 __ CallStub(&stub); 3747 __ CallStub(&stub);
3748 context()->Plug(v0); 3748 context()->Plug(v0);
3749 } 3749 }
3750 3750
3751 3751
3752 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { 3752 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
3753 ZoneList<Expression*>* args = expr->arguments(); 3753 ZoneList<Expression*>* args = expr->arguments();
3754 ASSERT_EQ(2, args->length()); 3754 DCHECK_EQ(2, args->length());
3755 3755
3756 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3756 DCHECK_NE(NULL, args->at(0)->AsLiteral());
3757 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); 3757 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
3758 3758
3759 Handle<FixedArray> jsfunction_result_caches( 3759 Handle<FixedArray> jsfunction_result_caches(
3760 isolate()->native_context()->jsfunction_result_caches()); 3760 isolate()->native_context()->jsfunction_result_caches());
3761 if (jsfunction_result_caches->length() <= cache_id) { 3761 if (jsfunction_result_caches->length() <= cache_id) {
3762 __ Abort(kAttemptToUseUndefinedCache); 3762 __ Abort(kAttemptToUseUndefinedCache);
3763 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 3763 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
3764 context()->Plug(v0); 3764 context()->Plug(v0);
3765 return; 3765 return;
3766 } 3766 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3819 3819
3820 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3820 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3821 Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through); 3821 Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through);
3822 3822
3823 context()->Plug(if_true, if_false); 3823 context()->Plug(if_true, if_false);
3824 } 3824 }
3825 3825
3826 3826
3827 void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { 3827 void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
3828 ZoneList<Expression*>* args = expr->arguments(); 3828 ZoneList<Expression*>* args = expr->arguments();
3829 ASSERT(args->length() == 1); 3829 DCHECK(args->length() == 1);
3830 VisitForAccumulatorValue(args->at(0)); 3830 VisitForAccumulatorValue(args->at(0));
3831 3831
3832 __ AssertString(v0); 3832 __ AssertString(v0);
3833 3833
3834 __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset)); 3834 __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset));
3835 __ IndexFromHash(v0, v0); 3835 __ IndexFromHash(v0, v0);
3836 3836
3837 context()->Plug(v0); 3837 context()->Plug(v0);
3838 } 3838 }
3839 3839
3840 3840
3841 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { 3841 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
3842 Label bailout, done, one_char_separator, long_separator, 3842 Label bailout, done, one_char_separator, long_separator,
3843 non_trivial_array, not_size_one_array, loop, 3843 non_trivial_array, not_size_one_array, loop,
3844 empty_separator_loop, one_char_separator_loop, 3844 empty_separator_loop, one_char_separator_loop,
3845 one_char_separator_loop_entry, long_separator_loop; 3845 one_char_separator_loop_entry, long_separator_loop;
3846 ZoneList<Expression*>* args = expr->arguments(); 3846 ZoneList<Expression*>* args = expr->arguments();
3847 ASSERT(args->length() == 2); 3847 DCHECK(args->length() == 2);
3848 VisitForStackValue(args->at(1)); 3848 VisitForStackValue(args->at(1));
3849 VisitForAccumulatorValue(args->at(0)); 3849 VisitForAccumulatorValue(args->at(0));
3850 3850
3851 // All aliases of the same register have disjoint lifetimes. 3851 // All aliases of the same register have disjoint lifetimes.
3852 Register array = v0; 3852 Register array = v0;
3853 Register elements = no_reg; // Will be v0. 3853 Register elements = no_reg; // Will be v0.
3854 Register result = no_reg; // Will be v0. 3854 Register result = no_reg; // Will be v0.
3855 Register separator = a1; 3855 Register separator = a1;
3856 Register array_length = a2; 3856 Register array_length = a2;
3857 Register result_pos = no_reg; // Will be a2. 3857 Register result_pos = no_reg; // Will be a2.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3998 3998
3999 // Copy next array element to the result. 3999 // Copy next array element to the result.
4000 __ lw(string, MemOperand(element)); 4000 __ lw(string, MemOperand(element));
4001 __ Addu(element, element, kPointerSize); 4001 __ Addu(element, element, kPointerSize);
4002 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset)); 4002 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset));
4003 __ SmiUntag(string_length); 4003 __ SmiUntag(string_length);
4004 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); 4004 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
4005 __ CopyBytes(string, result_pos, string_length, scratch1); 4005 __ CopyBytes(string, result_pos, string_length, scratch1);
4006 // End while (element < elements_end). 4006 // End while (element < elements_end).
4007 __ Branch(&empty_separator_loop, lt, element, Operand(elements_end)); 4007 __ Branch(&empty_separator_loop, lt, element, Operand(elements_end));
4008 ASSERT(result.is(v0)); 4008 DCHECK(result.is(v0));
4009 __ Branch(&done); 4009 __ Branch(&done);
4010 4010
4011 // One-character separator case. 4011 // One-character separator case.
4012 __ bind(&one_char_separator); 4012 __ bind(&one_char_separator);
4013 // Replace separator with its ASCII character value. 4013 // Replace separator with its ASCII character value.
4014 __ lbu(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize)); 4014 __ lbu(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
4015 // Jump into the loop after the code that copies the separator, so the first 4015 // Jump into the loop after the code that copies the separator, so the first
4016 // element is not preceded by a separator. 4016 // element is not preceded by a separator.
4017 __ jmp(&one_char_separator_loop_entry); 4017 __ jmp(&one_char_separator_loop_entry);
4018 4018
(...skipping 11 matching lines...) Expand all
4030 // Copy next array element to the result. 4030 // Copy next array element to the result.
4031 __ bind(&one_char_separator_loop_entry); 4031 __ bind(&one_char_separator_loop_entry);
4032 __ lw(string, MemOperand(element)); 4032 __ lw(string, MemOperand(element));
4033 __ Addu(element, element, kPointerSize); 4033 __ Addu(element, element, kPointerSize);
4034 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset)); 4034 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset));
4035 __ SmiUntag(string_length); 4035 __ SmiUntag(string_length);
4036 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); 4036 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
4037 __ CopyBytes(string, result_pos, string_length, scratch1); 4037 __ CopyBytes(string, result_pos, string_length, scratch1);
4038 // End while (element < elements_end). 4038 // End while (element < elements_end).
4039 __ Branch(&one_char_separator_loop, lt, element, Operand(elements_end)); 4039 __ Branch(&one_char_separator_loop, lt, element, Operand(elements_end));
4040 ASSERT(result.is(v0)); 4040 DCHECK(result.is(v0));
4041 __ Branch(&done); 4041 __ Branch(&done);
4042 4042
4043 // Long separator case (separator is more than one character). Entry is at the 4043 // Long separator case (separator is more than one character). Entry is at the
4044 // label long_separator below. 4044 // label long_separator below.
4045 __ bind(&long_separator_loop); 4045 __ bind(&long_separator_loop);
4046 // Live values in registers: 4046 // Live values in registers:
4047 // result_pos: the position to which we are currently copying characters. 4047 // result_pos: the position to which we are currently copying characters.
4048 // element: Current array element. 4048 // element: Current array element.
4049 // elements_end: Array end. 4049 // elements_end: Array end.
4050 // separator: Separator string. 4050 // separator: Separator string.
4051 4051
4052 // Copy the separator to the result. 4052 // Copy the separator to the result.
4053 __ lw(string_length, FieldMemOperand(separator, String::kLengthOffset)); 4053 __ lw(string_length, FieldMemOperand(separator, String::kLengthOffset));
4054 __ SmiUntag(string_length); 4054 __ SmiUntag(string_length);
4055 __ Addu(string, 4055 __ Addu(string,
4056 separator, 4056 separator,
4057 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4057 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4058 __ CopyBytes(string, result_pos, string_length, scratch1); 4058 __ CopyBytes(string, result_pos, string_length, scratch1);
4059 4059
4060 __ bind(&long_separator); 4060 __ bind(&long_separator);
4061 __ lw(string, MemOperand(element)); 4061 __ lw(string, MemOperand(element));
4062 __ Addu(element, element, kPointerSize); 4062 __ Addu(element, element, kPointerSize);
4063 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset)); 4063 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset));
4064 __ SmiUntag(string_length); 4064 __ SmiUntag(string_length);
4065 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); 4065 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
4066 __ CopyBytes(string, result_pos, string_length, scratch1); 4066 __ CopyBytes(string, result_pos, string_length, scratch1);
4067 // End while (element < elements_end). 4067 // End while (element < elements_end).
4068 __ Branch(&long_separator_loop, lt, element, Operand(elements_end)); 4068 __ Branch(&long_separator_loop, lt, element, Operand(elements_end));
4069 ASSERT(result.is(v0)); 4069 DCHECK(result.is(v0));
4070 __ Branch(&done); 4070 __ Branch(&done);
4071 4071
4072 __ bind(&bailout); 4072 __ bind(&bailout);
4073 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 4073 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
4074 __ bind(&done); 4074 __ bind(&done);
4075 context()->Plug(v0); 4075 context()->Plug(v0);
4076 } 4076 }
4077 4077
4078 4078
4079 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { 4079 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
4080 ASSERT(expr->arguments()->length() == 0); 4080 DCHECK(expr->arguments()->length() == 0);
4081 ExternalReference debug_is_active = 4081 ExternalReference debug_is_active =
4082 ExternalReference::debug_is_active_address(isolate()); 4082 ExternalReference::debug_is_active_address(isolate());
4083 __ li(at, Operand(debug_is_active)); 4083 __ li(at, Operand(debug_is_active));
4084 __ lb(v0, MemOperand(at)); 4084 __ lb(v0, MemOperand(at));
4085 __ SmiTag(v0); 4085 __ SmiTag(v0);
4086 context()->Plug(v0); 4086 context()->Plug(v0);
4087 } 4087 }
4088 4088
4089 4089
4090 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4090 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4161 VisitForStackValue(property->obj()); 4161 VisitForStackValue(property->obj());
4162 VisitForStackValue(property->key()); 4162 VisitForStackValue(property->key());
4163 __ li(a1, Operand(Smi::FromInt(strict_mode()))); 4163 __ li(a1, Operand(Smi::FromInt(strict_mode())));
4164 __ push(a1); 4164 __ push(a1);
4165 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4165 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4166 context()->Plug(v0); 4166 context()->Plug(v0);
4167 } else if (proxy != NULL) { 4167 } else if (proxy != NULL) {
4168 Variable* var = proxy->var(); 4168 Variable* var = proxy->var();
4169 // Delete of an unqualified identifier is disallowed in strict mode 4169 // Delete of an unqualified identifier is disallowed in strict mode
4170 // but "delete this" is allowed. 4170 // but "delete this" is allowed.
4171 ASSERT(strict_mode() == SLOPPY || var->is_this()); 4171 DCHECK(strict_mode() == SLOPPY || var->is_this());
4172 if (var->IsUnallocated()) { 4172 if (var->IsUnallocated()) {
4173 __ lw(a2, GlobalObjectOperand()); 4173 __ lw(a2, GlobalObjectOperand());
4174 __ li(a1, Operand(var->name())); 4174 __ li(a1, Operand(var->name()));
4175 __ li(a0, Operand(Smi::FromInt(SLOPPY))); 4175 __ li(a0, Operand(Smi::FromInt(SLOPPY)));
4176 __ Push(a2, a1, a0); 4176 __ Push(a2, a1, a0);
4177 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4177 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4178 context()->Plug(v0); 4178 context()->Plug(v0);
4179 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4179 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4180 // Result of deleting non-global, non-dynamic variables is false. 4180 // Result of deleting non-global, non-dynamic variables is false.
4181 // The subexpression does not have side effects. 4181 // The subexpression does not have side effects.
4182 context()->Plug(var->is_this()); 4182 context()->Plug(var->is_this());
4183 } else { 4183 } else {
4184 // Non-global variable. Call the runtime to try to delete from the 4184 // Non-global variable. Call the runtime to try to delete from the
4185 // context where the variable was introduced. 4185 // context where the variable was introduced.
4186 ASSERT(!context_register().is(a2)); 4186 DCHECK(!context_register().is(a2));
4187 __ li(a2, Operand(var->name())); 4187 __ li(a2, Operand(var->name()));
4188 __ Push(context_register(), a2); 4188 __ Push(context_register(), a2);
4189 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 4189 __ CallRuntime(Runtime::kDeleteLookupSlot, 2);
4190 context()->Plug(v0); 4190 context()->Plug(v0);
4191 } 4191 }
4192 } else { 4192 } else {
4193 // Result of deleting non-property, non-variable reference is true. 4193 // Result of deleting non-property, non-variable reference is true.
4194 // The subexpression may have side effects. 4194 // The subexpression may have side effects.
4195 VisitForEffect(expr->expression()); 4195 VisitForEffect(expr->expression());
4196 context()->Plug(true); 4196 context()->Plug(true);
(...skipping 20 matching lines...) Expand all
4217 VisitForControl(expr->expression(), 4217 VisitForControl(expr->expression(),
4218 test->false_label(), 4218 test->false_label(),
4219 test->true_label(), 4219 test->true_label(),
4220 test->fall_through()); 4220 test->fall_through());
4221 context()->Plug(test->true_label(), test->false_label()); 4221 context()->Plug(test->true_label(), test->false_label());
4222 } else { 4222 } else {
4223 // We handle value contexts explicitly rather than simply visiting 4223 // We handle value contexts explicitly rather than simply visiting
4224 // for control and plugging the control flow into the context, 4224 // for control and plugging the control flow into the context,
4225 // because we need to prepare a pair of extra administrative AST ids 4225 // because we need to prepare a pair of extra administrative AST ids
4226 // for the optimizing compiler. 4226 // for the optimizing compiler.
4227 ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue()); 4227 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
4228 Label materialize_true, materialize_false, done; 4228 Label materialize_true, materialize_false, done;
4229 VisitForControl(expr->expression(), 4229 VisitForControl(expr->expression(),
4230 &materialize_false, 4230 &materialize_false,
4231 &materialize_true, 4231 &materialize_true,
4232 &materialize_true); 4232 &materialize_true);
4233 __ bind(&materialize_true); 4233 __ bind(&materialize_true);
4234 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 4234 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
4235 __ LoadRoot(v0, Heap::kTrueValueRootIndex); 4235 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
4236 if (context()->IsStackValue()) __ push(v0); 4236 if (context()->IsStackValue()) __ push(v0);
4237 __ jmp(&done); 4237 __ jmp(&done);
(...skipping 16 matching lines...) Expand all
4254 break; 4254 break;
4255 } 4255 }
4256 4256
4257 default: 4257 default:
4258 UNREACHABLE(); 4258 UNREACHABLE();
4259 } 4259 }
4260 } 4260 }
4261 4261
4262 4262
4263 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4263 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4264 ASSERT(expr->expression()->IsValidReferenceExpression()); 4264 DCHECK(expr->expression()->IsValidReferenceExpression());
4265 4265
4266 Comment cmnt(masm_, "[ CountOperation"); 4266 Comment cmnt(masm_, "[ CountOperation");
4267 SetSourcePosition(expr->position()); 4267 SetSourcePosition(expr->position());
4268 4268
4269 // Expression can only be a property, a global or a (parameter or local) 4269 // Expression can only be a property, a global or a (parameter or local)
4270 // slot. 4270 // slot.
4271 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 4271 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
4272 LhsKind assign_type = VARIABLE; 4272 LhsKind assign_type = VARIABLE;
4273 Property* prop = expr->expression()->AsProperty(); 4273 Property* prop = expr->expression()->AsProperty();
4274 // In case of a property we use the uninitialized expression context 4274 // In case of a property we use the uninitialized expression context
4275 // of the key to detect a named property. 4275 // of the key to detect a named property.
4276 if (prop != NULL) { 4276 if (prop != NULL) {
4277 assign_type = 4277 assign_type =
4278 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 4278 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
4279 } 4279 }
4280 4280
4281 // Evaluate expression and get value. 4281 // Evaluate expression and get value.
4282 if (assign_type == VARIABLE) { 4282 if (assign_type == VARIABLE) {
4283 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 4283 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4284 AccumulatorValueContext context(this); 4284 AccumulatorValueContext context(this);
4285 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4285 EmitVariableLoad(expr->expression()->AsVariableProxy());
4286 } else { 4286 } else {
4287 // Reserve space for result of postfix operation. 4287 // Reserve space for result of postfix operation.
4288 if (expr->is_postfix() && !context()->IsEffect()) { 4288 if (expr->is_postfix() && !context()->IsEffect()) {
4289 __ li(at, Operand(Smi::FromInt(0))); 4289 __ li(at, Operand(Smi::FromInt(0)));
4290 __ push(at); 4290 __ push(at);
4291 } 4291 }
4292 if (assign_type == NAMED_PROPERTY) { 4292 if (assign_type == NAMED_PROPERTY) {
4293 // Put the object both on the stack and in the register. 4293 // Put the object both on the stack and in the register.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
4439 } else { 4439 } else {
4440 context()->Plug(v0); 4440 context()->Plug(v0);
4441 } 4441 }
4442 break; 4442 break;
4443 } 4443 }
4444 } 4444 }
4445 } 4445 }
4446 4446
4447 4447
4448 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4448 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4449 ASSERT(!context()->IsEffect()); 4449 DCHECK(!context()->IsEffect());
4450 ASSERT(!context()->IsTest()); 4450 DCHECK(!context()->IsTest());
4451 VariableProxy* proxy = expr->AsVariableProxy(); 4451 VariableProxy* proxy = expr->AsVariableProxy();
4452 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4452 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4453 Comment cmnt(masm_, "[ Global variable"); 4453 Comment cmnt(masm_, "[ Global variable");
4454 __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 4454 __ lw(LoadIC::ReceiverRegister(), GlobalObjectOperand());
4455 __ li(LoadIC::NameRegister(), Operand(proxy->name())); 4455 __ li(LoadIC::NameRegister(), Operand(proxy->name()));
4456 if (FLAG_vector_ics) { 4456 if (FLAG_vector_ics) {
4457 __ li(LoadIC::SlotRegister(), 4457 __ li(LoadIC::SlotRegister(),
4458 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); 4458 Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
4459 } 4459 }
4460 // Use a regular load, not a contextual load, to avoid a reference 4460 // Use a regular load, not a contextual load, to avoid a reference
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
4666 return v0; 4666 return v0;
4667 } 4667 }
4668 4668
4669 4669
4670 Register FullCodeGenerator::context_register() { 4670 Register FullCodeGenerator::context_register() {
4671 return cp; 4671 return cp;
4672 } 4672 }
4673 4673
4674 4674
4675 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4675 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4676 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4676 DCHECK_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
4677 __ sw(value, MemOperand(fp, frame_offset)); 4677 __ sw(value, MemOperand(fp, frame_offset));
4678 } 4678 }
4679 4679
4680 4680
4681 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 4681 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
4682 __ lw(dst, ContextOperand(cp, context_index)); 4682 __ lw(dst, ContextOperand(cp, context_index));
4683 } 4683 }
4684 4684
4685 4685
4686 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 4686 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
4687 Scope* declaration_scope = scope()->DeclarationScope(); 4687 Scope* declaration_scope = scope()->DeclarationScope();
4688 if (declaration_scope->is_global_scope() || 4688 if (declaration_scope->is_global_scope() ||
4689 declaration_scope->is_module_scope()) { 4689 declaration_scope->is_module_scope()) {
4690 // Contexts nested in the native context have a canonical empty function 4690 // Contexts nested in the native context have a canonical empty function
4691 // as their closure, not the anonymous closure containing the global 4691 // as their closure, not the anonymous closure containing the global
4692 // code. Pass a smi sentinel and let the runtime look up the empty 4692 // code. Pass a smi sentinel and let the runtime look up the empty
4693 // function. 4693 // function.
4694 __ li(at, Operand(Smi::FromInt(0))); 4694 __ li(at, Operand(Smi::FromInt(0)));
4695 } else if (declaration_scope->is_eval_scope()) { 4695 } else if (declaration_scope->is_eval_scope()) {
4696 // Contexts created by a call to eval have the same closure as the 4696 // Contexts created by a call to eval have the same closure as the
4697 // context calling eval, not the anonymous closure containing the eval 4697 // context calling eval, not the anonymous closure containing the eval
4698 // code. Fetch it from the context. 4698 // code. Fetch it from the context.
4699 __ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX)); 4699 __ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX));
4700 } else { 4700 } else {
4701 ASSERT(declaration_scope->is_function_scope()); 4701 DCHECK(declaration_scope->is_function_scope());
4702 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4702 __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4703 } 4703 }
4704 __ push(at); 4704 __ push(at);
4705 } 4705 }
4706 4706
4707 4707
4708 // ---------------------------------------------------------------------------- 4708 // ----------------------------------------------------------------------------
4709 // Non-local control flow support. 4709 // Non-local control flow support.
4710 4710
4711 void FullCodeGenerator::EnterFinallyBlock() { 4711 void FullCodeGenerator::EnterFinallyBlock() {
4712 ASSERT(!result_register().is(a1)); 4712 DCHECK(!result_register().is(a1));
4713 // Store result register while executing finally block. 4713 // Store result register while executing finally block.
4714 __ push(result_register()); 4714 __ push(result_register());
4715 // Cook return address in link register to stack (smi encoded Code* delta). 4715 // Cook return address in link register to stack (smi encoded Code* delta).
4716 __ Subu(a1, ra, Operand(masm_->CodeObject())); 4716 __ Subu(a1, ra, Operand(masm_->CodeObject()));
4717 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 4717 DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
4718 STATIC_ASSERT(0 == kSmiTag); 4718 STATIC_ASSERT(0 == kSmiTag);
4719 __ Addu(a1, a1, Operand(a1)); // Convert to smi. 4719 __ Addu(a1, a1, Operand(a1)); // Convert to smi.
4720 4720
4721 // Store result register while executing finally block. 4721 // Store result register while executing finally block.
4722 __ push(a1); 4722 __ push(a1);
4723 4723
4724 // Store pending message while executing finally block. 4724 // Store pending message while executing finally block.
4725 ExternalReference pending_message_obj = 4725 ExternalReference pending_message_obj =
4726 ExternalReference::address_of_pending_message_obj(isolate()); 4726 ExternalReference::address_of_pending_message_obj(isolate());
4727 __ li(at, Operand(pending_message_obj)); 4727 __ li(at, Operand(pending_message_obj));
4728 __ lw(a1, MemOperand(at)); 4728 __ lw(a1, MemOperand(at));
4729 __ push(a1); 4729 __ push(a1);
4730 4730
4731 ExternalReference has_pending_message = 4731 ExternalReference has_pending_message =
4732 ExternalReference::address_of_has_pending_message(isolate()); 4732 ExternalReference::address_of_has_pending_message(isolate());
4733 __ li(at, Operand(has_pending_message)); 4733 __ li(at, Operand(has_pending_message));
4734 __ lw(a1, MemOperand(at)); 4734 __ lw(a1, MemOperand(at));
4735 __ SmiTag(a1); 4735 __ SmiTag(a1);
4736 __ push(a1); 4736 __ push(a1);
4737 4737
4738 ExternalReference pending_message_script = 4738 ExternalReference pending_message_script =
4739 ExternalReference::address_of_pending_message_script(isolate()); 4739 ExternalReference::address_of_pending_message_script(isolate());
4740 __ li(at, Operand(pending_message_script)); 4740 __ li(at, Operand(pending_message_script));
4741 __ lw(a1, MemOperand(at)); 4741 __ lw(a1, MemOperand(at));
4742 __ push(a1); 4742 __ push(a1);
4743 } 4743 }
4744 4744
4745 4745
4746 void FullCodeGenerator::ExitFinallyBlock() { 4746 void FullCodeGenerator::ExitFinallyBlock() {
4747 ASSERT(!result_register().is(a1)); 4747 DCHECK(!result_register().is(a1));
4748 // Restore pending message from stack. 4748 // Restore pending message from stack.
4749 __ pop(a1); 4749 __ pop(a1);
4750 ExternalReference pending_message_script = 4750 ExternalReference pending_message_script =
4751 ExternalReference::address_of_pending_message_script(isolate()); 4751 ExternalReference::address_of_pending_message_script(isolate());
4752 __ li(at, Operand(pending_message_script)); 4752 __ li(at, Operand(pending_message_script));
4753 __ sw(a1, MemOperand(at)); 4753 __ sw(a1, MemOperand(at));
4754 4754
4755 __ pop(a1); 4755 __ pop(a1);
4756 __ SmiUntag(a1); 4756 __ SmiUntag(a1);
4757 ExternalReference has_pending_message = 4757 ExternalReference has_pending_message =
4758 ExternalReference::address_of_has_pending_message(isolate()); 4758 ExternalReference::address_of_has_pending_message(isolate());
4759 __ li(at, Operand(has_pending_message)); 4759 __ li(at, Operand(has_pending_message));
4760 __ sw(a1, MemOperand(at)); 4760 __ sw(a1, MemOperand(at));
4761 4761
4762 __ pop(a1); 4762 __ pop(a1);
4763 ExternalReference pending_message_obj = 4763 ExternalReference pending_message_obj =
4764 ExternalReference::address_of_pending_message_obj(isolate()); 4764 ExternalReference::address_of_pending_message_obj(isolate());
4765 __ li(at, Operand(pending_message_obj)); 4765 __ li(at, Operand(pending_message_obj));
4766 __ sw(a1, MemOperand(at)); 4766 __ sw(a1, MemOperand(at));
4767 4767
4768 // Restore result register from stack. 4768 // Restore result register from stack.
4769 __ pop(a1); 4769 __ pop(a1);
4770 4770
4771 // Uncook return address and return. 4771 // Uncook return address and return.
4772 __ pop(result_register()); 4772 __ pop(result_register());
4773 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 4773 DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
4774 __ sra(a1, a1, 1); // Un-smi-tag value. 4774 __ sra(a1, a1, 1); // Un-smi-tag value.
4775 __ Addu(at, a1, Operand(masm_->CodeObject())); 4775 __ Addu(at, a1, Operand(masm_->CodeObject()));
4776 __ Jump(at); 4776 __ Jump(at);
4777 } 4777 }
4778 4778
4779 4779
4780 #undef __ 4780 #undef __
4781 4781
4782 #define __ ACCESS_MASM(masm()) 4782 #define __ ACCESS_MASM(masm())
4783 4783
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4851 4851
4852 4852
4853 BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( 4853 BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
4854 Isolate* isolate, 4854 Isolate* isolate,
4855 Code* unoptimized_code, 4855 Code* unoptimized_code,
4856 Address pc) { 4856 Address pc) {
4857 static const int kInstrSize = Assembler::kInstrSize; 4857 static const int kInstrSize = Assembler::kInstrSize;
4858 Address branch_address = pc - 6 * kInstrSize; 4858 Address branch_address = pc - 6 * kInstrSize;
4859 Address pc_immediate_load_address = pc - 4 * kInstrSize; 4859 Address pc_immediate_load_address = pc - 4 * kInstrSize;
4860 4860
4861 ASSERT(Assembler::IsBeq(Assembler::instr_at(pc - 5 * kInstrSize))); 4861 DCHECK(Assembler::IsBeq(Assembler::instr_at(pc - 5 * kInstrSize)));
4862 if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) { 4862 if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) {
4863 ASSERT(reinterpret_cast<uint32_t>( 4863 DCHECK(reinterpret_cast<uint32_t>(
4864 Assembler::target_address_at(pc_immediate_load_address)) == 4864 Assembler::target_address_at(pc_immediate_load_address)) ==
4865 reinterpret_cast<uint32_t>( 4865 reinterpret_cast<uint32_t>(
4866 isolate->builtins()->InterruptCheck()->entry())); 4866 isolate->builtins()->InterruptCheck()->entry()));
4867 return INTERRUPT; 4867 return INTERRUPT;
4868 } 4868 }
4869 4869
4870 ASSERT(Assembler::IsAddImmediate(Assembler::instr_at(branch_address))); 4870 DCHECK(Assembler::IsAddImmediate(Assembler::instr_at(branch_address)));
4871 4871
4872 if (reinterpret_cast<uint32_t>( 4872 if (reinterpret_cast<uint32_t>(
4873 Assembler::target_address_at(pc_immediate_load_address)) == 4873 Assembler::target_address_at(pc_immediate_load_address)) ==
4874 reinterpret_cast<uint32_t>( 4874 reinterpret_cast<uint32_t>(
4875 isolate->builtins()->OnStackReplacement()->entry())) { 4875 isolate->builtins()->OnStackReplacement()->entry())) {
4876 return ON_STACK_REPLACEMENT; 4876 return ON_STACK_REPLACEMENT;
4877 } 4877 }
4878 4878
4879 ASSERT(reinterpret_cast<uint32_t>( 4879 DCHECK(reinterpret_cast<uint32_t>(
4880 Assembler::target_address_at(pc_immediate_load_address)) == 4880 Assembler::target_address_at(pc_immediate_load_address)) ==
4881 reinterpret_cast<uint32_t>( 4881 reinterpret_cast<uint32_t>(
4882 isolate->builtins()->OsrAfterStackCheck()->entry())); 4882 isolate->builtins()->OsrAfterStackCheck()->entry()));
4883 return OSR_AFTER_STACK_CHECK; 4883 return OSR_AFTER_STACK_CHECK;
4884 } 4884 }
4885 4885
4886 4886
4887 } } // namespace v8::internal 4887 } } // namespace v8::internal
4888 4888
4889 #endif // V8_TARGET_ARCH_MIPS 4889 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/disasm-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698