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

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

Issue 148573005: A64: Synchronize with r16249. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/lithium-codegen-mips.h ('k') | src/mips/lithium-gap-resolver-mips.h » ('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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 18 matching lines...) Expand all
29 29
30 #include "mips/lithium-codegen-mips.h" 30 #include "mips/lithium-codegen-mips.h"
31 #include "mips/lithium-gap-resolver-mips.h" 31 #include "mips/lithium-gap-resolver-mips.h"
32 #include "code-stubs.h" 32 #include "code-stubs.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 38
39 class SafepointGenerator : public CallWrapper { 39 class SafepointGenerator V8_FINAL : public CallWrapper {
40 public: 40 public:
41 SafepointGenerator(LCodeGen* codegen, 41 SafepointGenerator(LCodeGen* codegen,
42 LPointerMap* pointers, 42 LPointerMap* pointers,
43 Safepoint::DeoptMode mode) 43 Safepoint::DeoptMode mode)
44 : codegen_(codegen), 44 : codegen_(codegen),
45 pointers_(pointers), 45 pointers_(pointers),
46 deopt_mode_(mode) { } 46 deopt_mode_(mode) { }
47 virtual ~SafepointGenerator() { } 47 virtual ~SafepointGenerator() {}
48 48
49 virtual void BeforeCall(int call_size) const { } 49 virtual void BeforeCall(int call_size) const V8_OVERRIDE {}
50 50
51 virtual void AfterCall() const { 51 virtual void AfterCall() const V8_OVERRIDE {
52 codegen_->RecordSafepoint(pointers_, deopt_mode_); 52 codegen_->RecordSafepoint(pointers_, deopt_mode_);
53 } 53 }
54 54
55 private: 55 private:
56 LCodeGen* codegen_; 56 LCodeGen* codegen_;
57 LPointerMap* pointers_; 57 LPointerMap* pointers_;
58 Safepoint::DeoptMode deopt_mode_; 58 Safepoint::DeoptMode deopt_mode_;
59 }; 59 };
60 60
61 61
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 316 }
317 } 317 }
318 // Deferred code is the last part of the instruction sequence. Mark 318 // Deferred code is the last part of the instruction sequence. Mark
319 // the generated code as done unless we bailed out. 319 // the generated code as done unless we bailed out.
320 if (!is_aborted()) status_ = DONE; 320 if (!is_aborted()) status_ = DONE;
321 return !is_aborted(); 321 return !is_aborted();
322 } 322 }
323 323
324 324
325 bool LCodeGen::GenerateDeoptJumpTable() { 325 bool LCodeGen::GenerateDeoptJumpTable() {
326 // Check that the jump table is accessible from everywhere in the function
327 // code, i.e. that offsets to the table can be encoded in the 16bit signed
328 // immediate of a branch instruction.
329 // To simplify we consider the code size from the first instruction to the
330 // end of the jump table.
331 if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) +
332 deopt_jump_table_.length() * 12)) {
333 Abort(kGeneratedCodeIsTooLarge);
334 }
335
336 if (deopt_jump_table_.length() > 0) { 326 if (deopt_jump_table_.length() > 0) {
337 Comment(";;; -------------------- Jump table --------------------"); 327 Comment(";;; -------------------- Jump table --------------------");
338 } 328 }
339 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 329 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
340 Label table_start; 330 Label table_start;
341 __ bind(&table_start); 331 __ bind(&table_start);
342 Label needs_frame; 332 Label needs_frame;
343 for (int i = 0; i < deopt_jump_table_.length(); i++) { 333 for (int i = 0; i < deopt_jump_table_.length(); i++) {
344 __ bind(&deopt_jump_table_[i].label); 334 __ bind(&deopt_jump_table_[i].label);
345 Address entry = deopt_jump_table_[i].address; 335 Address entry = deopt_jump_table_[i].address;
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 int deoptimization_index = deoptimizations_.length(); 745 int deoptimization_index = deoptimizations_.length();
756 int pc_offset = masm()->pc_offset(); 746 int pc_offset = masm()->pc_offset();
757 environment->Register(deoptimization_index, 747 environment->Register(deoptimization_index,
758 translation.index(), 748 translation.index(),
759 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 749 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
760 deoptimizations_.Add(environment, zone()); 750 deoptimizations_.Add(environment, zone());
761 } 751 }
762 } 752 }
763 753
764 754
765 void LCodeGen::DeoptimizeIf(Condition cc, 755 void LCodeGen::DeoptimizeIf(Condition condition,
766 LEnvironment* environment, 756 LEnvironment* environment,
767 Deoptimizer::BailoutType bailout_type, 757 Deoptimizer::BailoutType bailout_type,
768 Register src1, 758 Register src1,
769 const Operand& src2) { 759 const Operand& src2) {
770 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 760 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
771 ASSERT(environment->HasBeenRegistered()); 761 ASSERT(environment->HasBeenRegistered());
772 int id = environment->deoptimization_index(); 762 int id = environment->deoptimization_index();
773 ASSERT(info()->IsOptimizing() || info()->IsStub()); 763 ASSERT(info()->IsOptimizing() || info()->IsStub());
774 Address entry = 764 Address entry =
775 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 765 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
776 if (entry == NULL) { 766 if (entry == NULL) {
777 Abort(kBailoutWasNotPrepared); 767 Abort(kBailoutWasNotPrepared);
778 return; 768 return;
779 } 769 }
780 770
781 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS. 771 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS.
782 if (FLAG_deopt_every_n_times == 1 && 772 if (FLAG_deopt_every_n_times == 1 &&
783 !info()->IsStub() && 773 !info()->IsStub() &&
784 info()->opt_count() == id) { 774 info()->opt_count() == id) {
785 ASSERT(frame_is_built_); 775 ASSERT(frame_is_built_);
786 __ Call(entry, RelocInfo::RUNTIME_ENTRY); 776 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
787 return; 777 return;
788 } 778 }
789 779
790 if (info()->ShouldTrapOnDeopt()) { 780 if (info()->ShouldTrapOnDeopt()) {
791 Label skip; 781 Label skip;
792 if (cc != al) { 782 if (condition != al) {
793 __ Branch(&skip, NegateCondition(cc), src1, src2); 783 __ Branch(&skip, NegateCondition(condition), src1, src2);
794 } 784 }
795 __ stop("trap_on_deopt"); 785 __ stop("trap_on_deopt");
796 __ bind(&skip); 786 __ bind(&skip);
797 } 787 }
798 788
799 ASSERT(info()->IsStub() || frame_is_built_); 789 ASSERT(info()->IsStub() || frame_is_built_);
800 if (cc == al && frame_is_built_) { 790 if (condition == al && frame_is_built_) {
801 __ Call(entry, RelocInfo::RUNTIME_ENTRY, cc, src1, src2); 791 __ Call(entry, RelocInfo::RUNTIME_ENTRY, condition, src1, src2);
802 } else { 792 } else {
803 // We often have several deopts to the same entry, reuse the last 793 // We often have several deopts to the same entry, reuse the last
804 // jump entry if this is the case. 794 // jump entry if this is the case.
805 if (deopt_jump_table_.is_empty() || 795 if (deopt_jump_table_.is_empty() ||
806 (deopt_jump_table_.last().address != entry) || 796 (deopt_jump_table_.last().address != entry) ||
807 (deopt_jump_table_.last().bailout_type != bailout_type) || 797 (deopt_jump_table_.last().bailout_type != bailout_type) ||
808 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { 798 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
809 Deoptimizer::JumpTableEntry table_entry(entry, 799 Deoptimizer::JumpTableEntry table_entry(entry,
810 bailout_type, 800 bailout_type,
811 !frame_is_built_); 801 !frame_is_built_);
812 deopt_jump_table_.Add(table_entry, zone()); 802 deopt_jump_table_.Add(table_entry, zone());
813 } 803 }
814 __ Branch(&deopt_jump_table_.last().label, cc, src1, src2); 804 __ Branch(&deopt_jump_table_.last().label, condition, src1, src2);
815 } 805 }
816 } 806 }
817 807
818 808
819 void LCodeGen::DeoptimizeIf(Condition cc, 809 void LCodeGen::DeoptimizeIf(Condition condition,
820 LEnvironment* environment, 810 LEnvironment* environment,
821 Register src1, 811 Register src1,
822 const Operand& src2) { 812 const Operand& src2) {
823 Deoptimizer::BailoutType bailout_type = info()->IsStub() 813 Deoptimizer::BailoutType bailout_type = info()->IsStub()
824 ? Deoptimizer::LAZY 814 ? Deoptimizer::LAZY
825 : Deoptimizer::EAGER; 815 : Deoptimizer::EAGER;
826 DeoptimizeIf(cc, environment, bailout_type, src1, src2); 816 DeoptimizeIf(condition, environment, bailout_type, src1, src2);
827 } 817 }
828 818
829 819
830 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 820 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
831 ZoneList<Handle<Map> > maps(1, zone()); 821 ZoneList<Handle<Map> > maps(1, zone());
832 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 822 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
833 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 823 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
834 RelocInfo::Mode mode = it.rinfo()->rmode(); 824 RelocInfo::Mode mode = it.rinfo()->rmode();
835 if (mode == RelocInfo::EMBEDDED_OBJECT && 825 if (mode == RelocInfo::EMBEDDED_OBJECT &&
836 it.rinfo()->target_object()->IsMap()) { 826 it.rinfo()->target_object()->IsMap()) {
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 1976
1987 int LCodeGen::GetNextEmittedBlock() const { 1977 int LCodeGen::GetNextEmittedBlock() const {
1988 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 1978 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
1989 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 1979 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
1990 } 1980 }
1991 return -1; 1981 return -1;
1992 } 1982 }
1993 1983
1994 template<class InstrType> 1984 template<class InstrType>
1995 void LCodeGen::EmitBranch(InstrType instr, 1985 void LCodeGen::EmitBranch(InstrType instr,
1996 Condition cc, Register src1, const Operand& src2) { 1986 Condition condition,
1987 Register src1,
1988 const Operand& src2) {
1997 int left_block = instr->TrueDestination(chunk_); 1989 int left_block = instr->TrueDestination(chunk_);
1998 int right_block = instr->FalseDestination(chunk_); 1990 int right_block = instr->FalseDestination(chunk_);
1999 1991
2000 int next_block = GetNextEmittedBlock(); 1992 int next_block = GetNextEmittedBlock();
2001 if (right_block == left_block || cc == al) { 1993 if (right_block == left_block || condition == al) {
2002 EmitGoto(left_block); 1994 EmitGoto(left_block);
2003 } else if (left_block == next_block) { 1995 } else if (left_block == next_block) {
2004 __ Branch(chunk_->GetAssemblyLabel(right_block), 1996 __ Branch(chunk_->GetAssemblyLabel(right_block),
2005 NegateCondition(cc), src1, src2); 1997 NegateCondition(condition), src1, src2);
2006 } else if (right_block == next_block) { 1998 } else if (right_block == next_block) {
2007 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); 1999 __ Branch(chunk_->GetAssemblyLabel(left_block), condition, src1, src2);
2008 } else { 2000 } else {
2009 __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); 2001 __ Branch(chunk_->GetAssemblyLabel(left_block), condition, src1, src2);
2010 __ Branch(chunk_->GetAssemblyLabel(right_block)); 2002 __ Branch(chunk_->GetAssemblyLabel(right_block));
2011 } 2003 }
2012 } 2004 }
2013 2005
2014 2006
2015 template<class InstrType> 2007 template<class InstrType>
2016 void LCodeGen::EmitBranchF(InstrType instr, 2008 void LCodeGen::EmitBranchF(InstrType instr,
2017 Condition cc, FPURegister src1, FPURegister src2) { 2009 Condition condition,
2010 FPURegister src1,
2011 FPURegister src2) {
2018 int right_block = instr->FalseDestination(chunk_); 2012 int right_block = instr->FalseDestination(chunk_);
2019 int left_block = instr->TrueDestination(chunk_); 2013 int left_block = instr->TrueDestination(chunk_);
2020 2014
2021 int next_block = GetNextEmittedBlock(); 2015 int next_block = GetNextEmittedBlock();
2022 if (right_block == left_block) { 2016 if (right_block == left_block) {
2023 EmitGoto(left_block); 2017 EmitGoto(left_block);
2024 } else if (left_block == next_block) { 2018 } else if (left_block == next_block) {
2025 __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL, 2019 __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL,
2026 NegateCondition(cc), src1, src2); 2020 NegateCondition(condition), src1, src2);
2027 } else if (right_block == next_block) { 2021 } else if (right_block == next_block) {
2028 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2); 2022 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL,
2023 condition, src1, src2);
2029 } else { 2024 } else {
2030 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2); 2025 __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL,
2026 condition, src1, src2);
2031 __ Branch(chunk_->GetAssemblyLabel(right_block)); 2027 __ Branch(chunk_->GetAssemblyLabel(right_block));
2032 } 2028 }
2033 } 2029 }
2034 2030
2035 2031
2032 template<class InstrType>
2033 void LCodeGen::EmitFalseBranchF(InstrType instr,
2034 Condition condition,
2035 FPURegister src1,
2036 FPURegister src2) {
2037 int false_block = instr->FalseDestination(chunk_);
2038 __ BranchF(chunk_->GetAssemblyLabel(false_block), NULL,
2039 condition, src1, src2);
2040 }
2041
2042
2036 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 2043 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2037 __ stop("LDebugBreak"); 2044 __ stop("LDebugBreak");
2038 } 2045 }
2039 2046
2040 2047
2041 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { 2048 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
2042 Representation r = instr->hydrogen()->value()->representation(); 2049 Representation r = instr->hydrogen()->value()->representation();
2043 if (r.IsSmiOrInteger32() || r.IsDouble()) { 2050 if (r.IsSmiOrInteger32() || r.IsDouble()) {
2044 EmitBranch(instr, al, zero_reg, Operand(zero_reg)); 2051 EmitBranch(instr, al, zero_reg, Operand(zero_reg));
2045 } else { 2052 } else {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 2293
2287 2294
2288 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2295 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2289 Register left = ToRegister(instr->left()); 2296 Register left = ToRegister(instr->left());
2290 Register right = ToRegister(instr->right()); 2297 Register right = ToRegister(instr->right());
2291 2298
2292 EmitBranch(instr, eq, left, Operand(right)); 2299 EmitBranch(instr, eq, left, Operand(right));
2293 } 2300 }
2294 2301
2295 2302
2303 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2304 if (instr->hydrogen()->representation().IsTagged()) {
2305 Register input_reg = ToRegister(instr->object());
2306 __ li(at, Operand(factory()->the_hole_value()));
2307 EmitBranch(instr, eq, input_reg, Operand(at));
2308 return;
2309 }
2310
2311 DoubleRegister input_reg = ToDoubleRegister(instr->object());
2312 EmitFalseBranchF(instr, eq, input_reg, input_reg);
2313
2314 Register scratch = scratch0();
2315 __ FmoveHigh(scratch, input_reg);
2316 EmitBranch(instr, eq, scratch, Operand(kHoleNanUpper32));
2317 }
2318
2319
2296 Condition LCodeGen::EmitIsObject(Register input, 2320 Condition LCodeGen::EmitIsObject(Register input,
2297 Register temp1, 2321 Register temp1,
2298 Register temp2, 2322 Register temp2,
2299 Label* is_not_object, 2323 Label* is_not_object,
2300 Label* is_object) { 2324 Label* is_object) {
2301 __ JumpIfSmi(input, is_not_object); 2325 __ JumpIfSmi(input, is_not_object);
2302 2326
2303 __ LoadRoot(temp2, Heap::kNullValueRootIndex); 2327 __ LoadRoot(temp2, Heap::kNullValueRootIndex);
2304 __ Branch(is_object, eq, input, Operand(temp2)); 2328 __ Branch(is_object, eq, input, Operand(temp2));
2305 2329
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2574 __ Branch(&true_label, eq, result, Operand(zero_reg)); 2598 __ Branch(&true_label, eq, result, Operand(zero_reg));
2575 __ li(result, Operand(factory()->false_value())); 2599 __ li(result, Operand(factory()->false_value()));
2576 __ Branch(&done); 2600 __ Branch(&done);
2577 __ bind(&true_label); 2601 __ bind(&true_label);
2578 __ li(result, Operand(factory()->true_value())); 2602 __ li(result, Operand(factory()->true_value()));
2579 __ bind(&done); 2603 __ bind(&done);
2580 } 2604 }
2581 2605
2582 2606
2583 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2607 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2584 class DeferredInstanceOfKnownGlobal: public LDeferredCode { 2608 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode {
2585 public: 2609 public:
2586 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 2610 DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
2587 LInstanceOfKnownGlobal* instr) 2611 LInstanceOfKnownGlobal* instr)
2588 : LDeferredCode(codegen), instr_(instr) { } 2612 : LDeferredCode(codegen), instr_(instr) { }
2589 virtual void Generate() { 2613 virtual void Generate() V8_OVERRIDE {
2590 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 2614 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
2591 } 2615 }
2592 virtual LInstruction* instr() { return instr_; } 2616 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
2593 Label* map_check() { return &map_check_; } 2617 Label* map_check() { return &map_check_; }
2594 2618
2595 private: 2619 private:
2596 LInstanceOfKnownGlobal* instr_; 2620 LInstanceOfKnownGlobal* instr_;
2597 Label map_check_; 2621 Label map_check_;
2598 }; 2622 };
2599 2623
2600 DeferredInstanceOfKnownGlobal* deferred; 2624 DeferredInstanceOfKnownGlobal* deferred;
2601 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2625 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2602 2626
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 Register result = ToRegister(instr->result()); 2938 Register result = ToRegister(instr->result());
2915 if (access.IsInobject()) { 2939 if (access.IsInobject()) {
2916 __ lw(result, FieldMemOperand(object, offset)); 2940 __ lw(result, FieldMemOperand(object, offset));
2917 } else { 2941 } else {
2918 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 2942 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2919 __ lw(result, FieldMemOperand(result, offset)); 2943 __ lw(result, FieldMemOperand(result, offset));
2920 } 2944 }
2921 } 2945 }
2922 2946
2923 2947
2924 void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
2925 Register object,
2926 Handle<Map> type,
2927 Handle<String> name,
2928 LEnvironment* env) {
2929 LookupResult lookup(isolate());
2930 type->LookupDescriptor(NULL, *name, &lookup);
2931 ASSERT(lookup.IsFound() || lookup.IsCacheable());
2932 if (lookup.IsField()) {
2933 int index = lookup.GetLocalFieldIndexFromMap(*type);
2934 int offset = index * kPointerSize;
2935 if (index < 0) {
2936 // Negative property indices are in-object properties, indexed
2937 // from the end of the fixed part of the object.
2938 __ lw(result, FieldMemOperand(object, offset + type->instance_size()));
2939 } else {
2940 // Non-negative property indices are in the properties array.
2941 __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
2942 __ lw(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
2943 }
2944 } else if (lookup.IsConstant()) {
2945 Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
2946 __ LoadObject(result, constant);
2947 } else {
2948 // Negative lookup.
2949 // Check prototypes.
2950 Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
2951 Heap* heap = type->GetHeap();
2952 while (*current != heap->null_value()) {
2953 __ LoadHeapObject(result, current);
2954 __ lw(result, FieldMemOperand(result, HeapObject::kMapOffset));
2955 DeoptimizeIf(ne, env, result, Operand(Handle<Map>(current->map())));
2956 current =
2957 Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
2958 }
2959 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2960 }
2961 }
2962
2963
2964 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2965 Register object = ToRegister(instr->object());
2966 Register result = ToRegister(instr->result());
2967 Register object_map = scratch0();
2968
2969 int map_count = instr->hydrogen()->types()->length();
2970 bool need_generic = instr->hydrogen()->need_generic();
2971
2972 if (map_count == 0 && !need_generic) {
2973 DeoptimizeIf(al, instr->environment());
2974 return;
2975 }
2976 Handle<String> name = instr->hydrogen()->name();
2977 Label done;
2978 __ lw(object_map, FieldMemOperand(object, HeapObject::kMapOffset));
2979 for (int i = 0; i < map_count; ++i) {
2980 bool last = (i == map_count - 1);
2981 Handle<Map> map = instr->hydrogen()->types()->at(i);
2982 Label check_passed;
2983 __ CompareMapAndBranch(object_map, map, &check_passed, eq, &check_passed);
2984 if (last && !need_generic) {
2985 DeoptimizeIf(al, instr->environment());
2986 __ bind(&check_passed);
2987 EmitLoadFieldOrConstantFunction(
2988 result, object, map, name, instr->environment());
2989 } else {
2990 Label next;
2991 __ Branch(&next);
2992 __ bind(&check_passed);
2993 EmitLoadFieldOrConstantFunction(
2994 result, object, map, name, instr->environment());
2995 __ Branch(&done);
2996 __ bind(&next);
2997 }
2998 }
2999 if (need_generic) {
3000 __ li(a2, Operand(name));
3001 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3002 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3003 }
3004 __ bind(&done);
3005 }
3006
3007
3008 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 2948 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3009 ASSERT(ToRegister(instr->object()).is(a0)); 2949 ASSERT(ToRegister(instr->object()).is(a0));
3010 ASSERT(ToRegister(instr->result()).is(v0)); 2950 ASSERT(ToRegister(instr->result()).is(v0));
3011 2951
3012 // Name is always in a2. 2952 // Name is always in a2.
3013 __ li(a2, Operand(instr->name())); 2953 __ li(a2, Operand(instr->name()));
3014 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2954 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3015 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2955 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3016 } 2956 }
3017 2957
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
3652 __ mov(result, input); 3592 __ mov(result, input);
3653 __ subu(result, zero_reg, input); 3593 __ subu(result, zero_reg, input);
3654 // Overflow if result is still negative, i.e. 0x80000000. 3594 // Overflow if result is still negative, i.e. 0x80000000.
3655 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 3595 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
3656 __ bind(&done); 3596 __ bind(&done);
3657 } 3597 }
3658 3598
3659 3599
3660 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3600 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3661 // Class for deferred case. 3601 // Class for deferred case.
3662 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3602 class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode {
3663 public: 3603 public:
3664 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3604 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3665 : LDeferredCode(codegen), instr_(instr) { } 3605 : LDeferredCode(codegen), instr_(instr) { }
3666 virtual void Generate() { 3606 virtual void Generate() V8_OVERRIDE {
3667 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3607 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3668 } 3608 }
3669 virtual LInstruction* instr() { return instr_; } 3609 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3670 private: 3610 private:
3671 LMathAbs* instr_; 3611 LMathAbs* instr_;
3672 }; 3612 };
3673 3613
3674 Representation r = instr->hydrogen()->value()->representation(); 3614 Representation r = instr->hydrogen()->value()->representation();
3675 if (r.IsDouble()) { 3615 if (r.IsDouble()) {
3676 FPURegister input = ToDoubleRegister(instr->value()); 3616 FPURegister input = ToDoubleRegister(instr->value());
3677 FPURegister result = ToDoubleRegister(instr->result()); 3617 FPURegister result = ToDoubleRegister(instr->result());
3678 __ abs_d(result, input); 3618 __ abs_d(result, input);
3679 } else if (r.IsSmiOrInteger32()) { 3619 } else if (r.IsSmiOrInteger32()) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
3854 __ CallStub(&stub); 3794 __ CallStub(&stub);
3855 } else { 3795 } else {
3856 ASSERT(exponent_type.IsDouble()); 3796 ASSERT(exponent_type.IsDouble());
3857 MathPowStub stub(MathPowStub::DOUBLE); 3797 MathPowStub stub(MathPowStub::DOUBLE);
3858 __ CallStub(&stub); 3798 __ CallStub(&stub);
3859 } 3799 }
3860 } 3800 }
3861 3801
3862 3802
3863 void LCodeGen::DoRandom(LRandom* instr) { 3803 void LCodeGen::DoRandom(LRandom* instr) {
3864 class DeferredDoRandom: public LDeferredCode { 3804 class DeferredDoRandom V8_FINAL : public LDeferredCode {
3865 public: 3805 public:
3866 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3806 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3867 : LDeferredCode(codegen), instr_(instr) { } 3807 : LDeferredCode(codegen), instr_(instr) { }
3868 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3808 virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
3869 virtual LInstruction* instr() { return instr_; } 3809 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3870 private: 3810 private:
3871 LRandom* instr_; 3811 LRandom* instr_;
3872 }; 3812 };
3873 3813
3874 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3814 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3875 // Having marked this instruction as a call we can use any 3815 // Having marked this instruction as a call we can use any
3876 // registers. 3816 // registers.
3877 ASSERT(ToDoubleRegister(instr->result()).is(f0)); 3817 ASSERT(ToDoubleRegister(instr->result()).is(f0));
3878 ASSERT(ToRegister(instr->global_object()).is(a0)); 3818 ASSERT(ToRegister(instr->global_object()).is(a0));
3879 3819
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
4226 4166
4227 // Name is always in a2. 4167 // Name is always in a2.
4228 __ li(a2, Operand(instr->name())); 4168 __ li(a2, Operand(instr->name()));
4229 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4169 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4230 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4170 ? isolate()->builtins()->StoreIC_Initialize_Strict()
4231 : isolate()->builtins()->StoreIC_Initialize(); 4171 : isolate()->builtins()->StoreIC_Initialize();
4232 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4172 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4233 } 4173 }
4234 4174
4235 4175
4236 void LCodeGen::ApplyCheckIf(Condition cc, 4176 void LCodeGen::ApplyCheckIf(Condition condition,
4237 LBoundsCheck* check, 4177 LBoundsCheck* check,
4238 Register src1, 4178 Register src1,
4239 const Operand& src2) { 4179 const Operand& src2) {
4240 if (FLAG_debug_code && check->hydrogen()->skip_check()) { 4180 if (FLAG_debug_code && check->hydrogen()->skip_check()) {
4241 Label done; 4181 Label done;
4242 __ Branch(&done, NegateCondition(cc), src1, src2); 4182 __ Branch(&done, NegateCondition(condition), src1, src2);
4243 __ stop("eliminated bounds check failed"); 4183 __ stop("eliminated bounds check failed");
4244 __ bind(&done); 4184 __ bind(&done);
4245 } else { 4185 } else {
4246 DeoptimizeIf(cc, check->environment(), src1, src2); 4186 DeoptimizeIf(condition, check->environment(), src1, src2);
4247 } 4187 }
4248 } 4188 }
4249 4189
4250 4190
4251 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4191 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4252 if (instr->hydrogen()->skip_check()) return; 4192 if (instr->hydrogen()->skip_check()) return;
4253 4193
4254 Condition condition = instr->hydrogen()->allow_equality() ? hi : hs; 4194 Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
4255 if (instr->index()->IsConstantOperand()) { 4195 if (instr->index()->IsConstantOperand()) {
4256 int constant_index = 4196 int constant_index =
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
4482 __ Branch(&not_applicable, ne, scratch, Operand(from_map)); 4422 __ Branch(&not_applicable, ne, scratch, Operand(from_map));
4483 4423
4484 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 4424 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
4485 Register new_map_reg = ToRegister(instr->new_map_temp()); 4425 Register new_map_reg = ToRegister(instr->new_map_temp());
4486 __ li(new_map_reg, Operand(to_map)); 4426 __ li(new_map_reg, Operand(to_map));
4487 __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 4427 __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
4488 // Write barrier. 4428 // Write barrier.
4489 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 4429 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
4490 scratch, GetRAState(), kDontSaveFPRegs); 4430 scratch, GetRAState(), kDontSaveFPRegs);
4491 } else { 4431 } else {
4492 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4432 PushSafepointRegistersScope scope(
4433 this, Safepoint::kWithRegistersAndDoubles);
4493 __ mov(a0, object_reg); 4434 __ mov(a0, object_reg);
4494 __ li(a1, Operand(to_map)); 4435 __ li(a1, Operand(to_map));
4495 TransitionElementsKindStub stub(from_kind, to_kind); 4436 TransitionElementsKindStub stub(from_kind, to_kind);
4496 __ CallStub(&stub); 4437 __ CallStub(&stub);
4497 RecordSafepointWithRegisters( 4438 RecordSafepointWithRegistersAndDoubles(
4498 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4439 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4499 } 4440 }
4500 __ bind(&not_applicable); 4441 __ bind(&not_applicable);
4501 } 4442 }
4502 4443
4503 4444
4504 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4445 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4505 Register object = ToRegister(instr->object()); 4446 Register object = ToRegister(instr->object());
4506 Register temp = ToRegister(instr->temp()); 4447 Register temp = ToRegister(instr->temp());
4507 Label fail; 4448 Label fail;
4508 __ TestJSArrayForAllocationMemento(object, temp, ne, &fail); 4449 __ TestJSArrayForAllocationMemento(object, temp, ne, &fail);
4509 DeoptimizeIf(al, instr->environment()); 4450 DeoptimizeIf(al, instr->environment());
4510 __ bind(&fail); 4451 __ bind(&fail);
4511 } 4452 }
4512 4453
4513 4454
4514 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4455 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4515 __ push(ToRegister(instr->left())); 4456 __ push(ToRegister(instr->left()));
4516 __ push(ToRegister(instr->right())); 4457 __ push(ToRegister(instr->right()));
4517 StringAddStub stub(instr->hydrogen()->flags()); 4458 StringAddStub stub(instr->hydrogen()->flags());
4518 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4459 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4519 } 4460 }
4520 4461
4521 4462
4522 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4463 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4523 class DeferredStringCharCodeAt: public LDeferredCode { 4464 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
4524 public: 4465 public:
4525 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 4466 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4526 : LDeferredCode(codegen), instr_(instr) { } 4467 : LDeferredCode(codegen), instr_(instr) { }
4527 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 4468 virtual void Generate() V8_OVERRIDE {
4528 virtual LInstruction* instr() { return instr_; } 4469 codegen()->DoDeferredStringCharCodeAt(instr_);
4470 }
4471 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4529 private: 4472 private:
4530 LStringCharCodeAt* instr_; 4473 LStringCharCodeAt* instr_;
4531 }; 4474 };
4532 4475
4533 DeferredStringCharCodeAt* deferred = 4476 DeferredStringCharCodeAt* deferred =
4534 new(zone()) DeferredStringCharCodeAt(this, instr); 4477 new(zone()) DeferredStringCharCodeAt(this, instr);
4535 StringCharLoadGenerator::Generate(masm(), 4478 StringCharLoadGenerator::Generate(masm(),
4536 ToRegister(instr->string()), 4479 ToRegister(instr->string()),
4537 ToRegister(instr->index()), 4480 ToRegister(instr->index()),
4538 ToRegister(instr->result()), 4481 ToRegister(instr->result()),
(...skipping 26 matching lines...) Expand all
4565 __ push(index); 4508 __ push(index);
4566 } 4509 }
4567 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); 4510 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
4568 __ AssertSmi(v0); 4511 __ AssertSmi(v0);
4569 __ SmiUntag(v0); 4512 __ SmiUntag(v0);
4570 __ StoreToSafepointRegisterSlot(v0, result); 4513 __ StoreToSafepointRegisterSlot(v0, result);
4571 } 4514 }
4572 4515
4573 4516
4574 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 4517 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4575 class DeferredStringCharFromCode: public LDeferredCode { 4518 class DeferredStringCharFromCode V8_FINAL : public LDeferredCode {
4576 public: 4519 public:
4577 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 4520 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4578 : LDeferredCode(codegen), instr_(instr) { } 4521 : LDeferredCode(codegen), instr_(instr) { }
4579 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 4522 virtual void Generate() V8_OVERRIDE {
4580 virtual LInstruction* instr() { return instr_; } 4523 codegen()->DoDeferredStringCharFromCode(instr_);
4524 }
4525 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4581 private: 4526 private:
4582 LStringCharFromCode* instr_; 4527 LStringCharFromCode* instr_;
4583 }; 4528 };
4584 4529
4585 DeferredStringCharFromCode* deferred = 4530 DeferredStringCharFromCode* deferred =
4586 new(zone()) DeferredStringCharFromCode(this, instr); 4531 new(zone()) DeferredStringCharFromCode(this, instr);
4587 4532
4588 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 4533 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4589 Register char_code = ToRegister(instr->char_code()); 4534 Register char_code = ToRegister(instr->char_code());
4590 Register result = ToRegister(instr->result()); 4535 Register result = ToRegister(instr->result());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
4656 LOperand* input = instr->value(); 4601 LOperand* input = instr->value();
4657 LOperand* output = instr->result(); 4602 LOperand* output = instr->result();
4658 4603
4659 FPURegister dbl_scratch = double_scratch0(); 4604 FPURegister dbl_scratch = double_scratch0();
4660 __ mtc1(ToRegister(input), dbl_scratch); 4605 __ mtc1(ToRegister(input), dbl_scratch);
4661 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); 4606 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22);
4662 } 4607 }
4663 4608
4664 4609
4665 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4610 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4666 class DeferredNumberTagI: public LDeferredCode { 4611 class DeferredNumberTagI V8_FINAL : public LDeferredCode {
4667 public: 4612 public:
4668 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4613 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4669 : LDeferredCode(codegen), instr_(instr) { } 4614 : LDeferredCode(codegen), instr_(instr) { }
4670 virtual void Generate() { 4615 virtual void Generate() V8_OVERRIDE {
4671 codegen()->DoDeferredNumberTagI(instr_, 4616 codegen()->DoDeferredNumberTagI(instr_,
4672 instr_->value(), 4617 instr_->value(),
4673 SIGNED_INT32); 4618 SIGNED_INT32);
4674 } 4619 }
4675 virtual LInstruction* instr() { return instr_; } 4620 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4676 private: 4621 private:
4677 LNumberTagI* instr_; 4622 LNumberTagI* instr_;
4678 }; 4623 };
4679 4624
4680 Register src = ToRegister(instr->value()); 4625 Register src = ToRegister(instr->value());
4681 Register dst = ToRegister(instr->result()); 4626 Register dst = ToRegister(instr->result());
4682 Register overflow = scratch0(); 4627 Register overflow = scratch0();
4683 4628
4684 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4629 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4685 __ SmiTagCheckOverflow(dst, src, overflow); 4630 __ SmiTagCheckOverflow(dst, src, overflow);
4686 __ BranchOnOverflow(deferred->entry(), overflow); 4631 __ BranchOnOverflow(deferred->entry(), overflow);
4687 __ bind(deferred->exit()); 4632 __ bind(deferred->exit());
4688 } 4633 }
4689 4634
4690 4635
4691 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4636 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4692 class DeferredNumberTagU: public LDeferredCode { 4637 class DeferredNumberTagU V8_FINAL : public LDeferredCode {
4693 public: 4638 public:
4694 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4639 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4695 : LDeferredCode(codegen), instr_(instr) { } 4640 : LDeferredCode(codegen), instr_(instr) { }
4696 virtual void Generate() { 4641 virtual void Generate() V8_OVERRIDE {
4697 codegen()->DoDeferredNumberTagI(instr_, 4642 codegen()->DoDeferredNumberTagI(instr_,
4698 instr_->value(), 4643 instr_->value(),
4699 UNSIGNED_INT32); 4644 UNSIGNED_INT32);
4700 } 4645 }
4701 virtual LInstruction* instr() { return instr_; } 4646 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4702 private: 4647 private:
4703 LNumberTagU* instr_; 4648 LNumberTagU* instr_;
4704 }; 4649 };
4705 4650
4706 LOperand* input = instr->value(); 4651 LOperand* input = instr->value();
4707 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4652 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4708 Register reg = ToRegister(input); 4653 Register reg = ToRegister(input);
4709 4654
4710 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4655 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4711 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); 4656 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4762 // Done. Put the value in dbl_scratch into the value of the allocated heap 4707 // Done. Put the value in dbl_scratch into the value of the allocated heap
4763 // number. 4708 // number.
4764 __ bind(&done); 4709 __ bind(&done);
4765 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); 4710 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset));
4766 __ Addu(dst, dst, kHeapObjectTag); 4711 __ Addu(dst, dst, kHeapObjectTag);
4767 __ StoreToSafepointRegisterSlot(dst, dst); 4712 __ StoreToSafepointRegisterSlot(dst, dst);
4768 } 4713 }
4769 4714
4770 4715
4771 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4716 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4772 class DeferredNumberTagD: public LDeferredCode { 4717 class DeferredNumberTagD V8_FINAL : public LDeferredCode {
4773 public: 4718 public:
4774 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4719 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4775 : LDeferredCode(codegen), instr_(instr) { } 4720 : LDeferredCode(codegen), instr_(instr) { }
4776 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4721 virtual void Generate() V8_OVERRIDE {
4777 virtual LInstruction* instr() { return instr_; } 4722 codegen()->DoDeferredNumberTagD(instr_);
4723 }
4724 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4778 private: 4725 private:
4779 LNumberTagD* instr_; 4726 LNumberTagD* instr_;
4780 }; 4727 };
4781 4728
4782 DoubleRegister input_reg = ToDoubleRegister(instr->value()); 4729 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4783 Register scratch = scratch0(); 4730 Register scratch = scratch0();
4784 Register reg = ToRegister(instr->result()); 4731 Register reg = ToRegister(instr->result());
4785 Register temp1 = ToRegister(instr->temp()); 4732 Register temp1 = ToRegister(instr->temp());
4786 Register temp2 = ToRegister(instr->temp2()); 4733 Register temp2 = ToRegister(instr->temp2());
4787 4734
4788 bool convert_hole = false;
4789 HValue* change_input = instr->hydrogen()->value();
4790 if (change_input->IsLoadKeyed()) {
4791 HLoadKeyed* load = HLoadKeyed::cast(change_input);
4792 convert_hole = load->UsesMustHandleHole();
4793 }
4794
4795 Label no_special_nan_handling;
4796 Label done;
4797 if (convert_hole) {
4798 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4799 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg);
4800 __ Move(reg, scratch0(), input_reg);
4801 Label canonicalize;
4802 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32));
4803 __ li(reg, factory()->the_hole_value());
4804 __ Branch(&done);
4805 __ bind(&canonicalize);
4806 __ Move(input_reg,
4807 FixedDoubleArray::canonical_not_the_hole_nan_as_double());
4808 }
4809
4810 __ bind(&no_special_nan_handling);
4811 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4735 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4812 if (FLAG_inline_new) { 4736 if (FLAG_inline_new) {
4813 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4737 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4814 // We want the untagged address first for performance 4738 // We want the untagged address first for performance
4815 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 4739 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
4816 DONT_TAG_RESULT); 4740 DONT_TAG_RESULT);
4817 } else { 4741 } else {
4818 __ Branch(deferred->entry()); 4742 __ Branch(deferred->entry());
4819 } 4743 }
4820 __ bind(deferred->exit()); 4744 __ bind(deferred->exit());
4821 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); 4745 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset));
4822 // Now that we have finished with the object's real address tag it 4746 // Now that we have finished with the object's real address tag it
4823 __ Addu(reg, reg, kHeapObjectTag); 4747 __ Addu(reg, reg, kHeapObjectTag);
4824 __ bind(&done);
4825 } 4748 }
4826 4749
4827 4750
4828 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4751 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4829 // TODO(3095996): Get rid of this. For now, we need to make the 4752 // TODO(3095996): Get rid of this. For now, we need to make the
4830 // result register contain a valid pointer because it is already 4753 // result register contain a valid pointer because it is already
4831 // contained in the register pointer map. 4754 // contained in the register pointer map.
4832 Register reg = ToRegister(instr->result()); 4755 Register reg = ToRegister(instr->result());
4833 __ mov(reg, zero_reg); 4756 __ mov(reg, zero_reg);
4834 4757
(...skipping 21 matching lines...) Expand all
4856 __ SmiUntag(result, input); 4779 __ SmiUntag(result, input);
4857 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 4780 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
4858 } else { 4781 } else {
4859 __ SmiUntag(result, input); 4782 __ SmiUntag(result, input);
4860 } 4783 }
4861 } 4784 }
4862 4785
4863 4786
4864 void LCodeGen::EmitNumberUntagD(Register input_reg, 4787 void LCodeGen::EmitNumberUntagD(Register input_reg,
4865 DoubleRegister result_reg, 4788 DoubleRegister result_reg,
4866 bool allow_undefined_as_nan, 4789 bool can_convert_undefined_to_nan,
4867 bool deoptimize_on_minus_zero, 4790 bool deoptimize_on_minus_zero,
4868 LEnvironment* env, 4791 LEnvironment* env,
4869 NumberUntagDMode mode) { 4792 NumberUntagDMode mode) {
4870 Register scratch = scratch0(); 4793 Register scratch = scratch0();
4871 4794
4872 Label load_smi, heap_number, done; 4795 Label load_smi, heap_number, done;
4873 4796
4874 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE > 4797 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4875 NUMBER_CANDIDATE_IS_ANY_TAGGED);
4876 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4877 // Smi check. 4798 // Smi check.
4878 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4799 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4879 4800
4880 // Heap number map check. 4801 // Heap number map check.
4881 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4802 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4882 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4803 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4883 if (!allow_undefined_as_nan) { 4804 if (!can_convert_undefined_to_nan) {
4884 DeoptimizeIf(ne, env, scratch, Operand(at)); 4805 DeoptimizeIf(ne, env, scratch, Operand(at));
4885 } else { 4806 } else {
4886 Label heap_number, convert; 4807 Label heap_number, convert;
4887 __ Branch(&heap_number, eq, scratch, Operand(at)); 4808 __ Branch(&heap_number, eq, scratch, Operand(at));
4888 4809
4889 // Convert undefined (and hole) to NaN. 4810 // Convert undefined (and hole) to NaN.
4890 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4811 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4891 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
4892 __ Branch(&convert, eq, input_reg, Operand(at));
4893 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
4894 }
4895 DeoptimizeIf(ne, env, input_reg, Operand(at)); 4812 DeoptimizeIf(ne, env, input_reg, Operand(at));
4896 4813
4897 __ bind(&convert); 4814 __ bind(&convert);
4898 __ LoadRoot(at, Heap::kNanValueRootIndex); 4815 __ LoadRoot(at, Heap::kNanValueRootIndex);
4899 __ ldc1(result_reg, FieldMemOperand(at, HeapNumber::kValueOffset)); 4816 __ ldc1(result_reg, FieldMemOperand(at, HeapNumber::kValueOffset));
4900 __ Branch(&done); 4817 __ Branch(&done);
4901 4818
4902 __ bind(&heap_number); 4819 __ bind(&heap_number);
4903 } 4820 }
4904 // Heap number to double register conversion. 4821 // Heap number to double register conversion.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
4996 __ mfc1(scratch1, double_scratch.high()); 4913 __ mfc1(scratch1, double_scratch.high());
4997 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 4914 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
4998 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 4915 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
4999 } 4916 }
5000 } 4917 }
5001 __ bind(&done); 4918 __ bind(&done);
5002 } 4919 }
5003 4920
5004 4921
5005 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4922 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
5006 class DeferredTaggedToI: public LDeferredCode { 4923 class DeferredTaggedToI V8_FINAL : public LDeferredCode {
5007 public: 4924 public:
5008 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4925 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
5009 : LDeferredCode(codegen), instr_(instr) { } 4926 : LDeferredCode(codegen), instr_(instr) { }
5010 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4927 virtual void Generate() V8_OVERRIDE {
5011 virtual LInstruction* instr() { return instr_; } 4928 codegen()->DoDeferredTaggedToI(instr_);
4929 }
4930 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5012 private: 4931 private:
5013 LTaggedToI* instr_; 4932 LTaggedToI* instr_;
5014 }; 4933 };
5015 4934
5016 LOperand* input = instr->value(); 4935 LOperand* input = instr->value();
5017 ASSERT(input->IsRegister()); 4936 ASSERT(input->IsRegister());
5018 ASSERT(input->Equals(instr->result())); 4937 ASSERT(input->Equals(instr->result()));
5019 4938
5020 Register input_reg = ToRegister(input); 4939 Register input_reg = ToRegister(input);
5021 4940
(...skipping 10 matching lines...) Expand all
5032 4951
5033 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4952 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5034 LOperand* input = instr->value(); 4953 LOperand* input = instr->value();
5035 ASSERT(input->IsRegister()); 4954 ASSERT(input->IsRegister());
5036 LOperand* result = instr->result(); 4955 LOperand* result = instr->result();
5037 ASSERT(result->IsDoubleRegister()); 4956 ASSERT(result->IsDoubleRegister());
5038 4957
5039 Register input_reg = ToRegister(input); 4958 Register input_reg = ToRegister(input);
5040 DoubleRegister result_reg = ToDoubleRegister(result); 4959 DoubleRegister result_reg = ToDoubleRegister(result);
5041 4960
5042 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
5043 HValue* value = instr->hydrogen()->value(); 4961 HValue* value = instr->hydrogen()->value();
5044 if (value->type().IsSmi()) { 4962 NumberUntagDMode mode = value->representation().IsSmi()
5045 mode = NUMBER_CANDIDATE_IS_SMI; 4963 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
5046 } else if (value->IsLoadKeyed()) {
5047 HLoadKeyed* load = HLoadKeyed::cast(value);
5048 if (load->UsesMustHandleHole()) {
5049 if (load->hole_mode() == ALLOW_RETURN_HOLE) {
5050 mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE;
5051 }
5052 }
5053 }
5054 4964
5055 EmitNumberUntagD(input_reg, result_reg, 4965 EmitNumberUntagD(input_reg, result_reg,
5056 instr->hydrogen()->allow_undefined_as_nan(), 4966 instr->hydrogen()->can_convert_undefined_to_nan(),
5057 instr->hydrogen()->deoptimize_on_minus_zero(), 4967 instr->hydrogen()->deoptimize_on_minus_zero(),
5058 instr->environment(), 4968 instr->environment(),
5059 mode); 4969 mode);
5060 } 4970 }
5061 4971
5062 4972
5063 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4973 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5064 Register result_reg = ToRegister(instr->result()); 4974 Register result_reg = ToRegister(instr->result());
5065 Register scratch1 = scratch0(); 4975 Register scratch1 = scratch0();
5066 Register scratch2 = ToRegister(instr->temp()); 4976 Register scratch2 = ToRegister(instr->temp());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
5198 } 5108 }
5199 } 5109 }
5200 5110
5201 5111
5202 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 5112 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
5203 Register reg = ToRegister(instr->value()); 5113 Register reg = ToRegister(instr->value());
5204 Handle<JSFunction> target = instr->hydrogen()->target(); 5114 Handle<JSFunction> target = instr->hydrogen()->target();
5205 AllowDeferredHandleDereference smi_check; 5115 AllowDeferredHandleDereference smi_check;
5206 if (isolate()->heap()->InNewSpace(*target)) { 5116 if (isolate()->heap()->InNewSpace(*target)) {
5207 Register reg = ToRegister(instr->value()); 5117 Register reg = ToRegister(instr->value());
5208 Handle<Cell> cell = isolate()->factory()->NewPropertyCell(target); 5118 Handle<Cell> cell = isolate()->factory()->NewCell(target);
5209 __ li(at, Operand(Handle<Object>(cell))); 5119 __ li(at, Operand(Handle<Object>(cell)));
5210 __ lw(at, FieldMemOperand(at, Cell::kValueOffset)); 5120 __ lw(at, FieldMemOperand(at, Cell::kValueOffset));
5211 DeoptimizeIf(ne, instr->environment(), reg, 5121 DeoptimizeIf(ne, instr->environment(), reg,
5212 Operand(at)); 5122 Operand(at));
5213 } else { 5123 } else {
5214 DeoptimizeIf(ne, instr->environment(), reg, 5124 DeoptimizeIf(ne, instr->environment(), reg,
5215 Operand(target)); 5125 Operand(target));
5216 } 5126 }
5217 } 5127 }
5218 5128
5219 5129
5220 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5130 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5221 { 5131 {
5222 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 5132 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5223 __ push(object); 5133 __ push(object);
5224 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); 5134 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
5225 __ StoreToSafepointRegisterSlot(v0, scratch0()); 5135 __ StoreToSafepointRegisterSlot(v0, scratch0());
5226 } 5136 }
5227 __ And(at, scratch0(), Operand(kSmiTagMask)); 5137 __ And(at, scratch0(), Operand(kSmiTagMask));
5228 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 5138 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
5229 } 5139 }
5230 5140
5231 5141
5232 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5142 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5233 class DeferredCheckMaps: public LDeferredCode { 5143 class DeferredCheckMaps V8_FINAL : public LDeferredCode {
5234 public: 5144 public:
5235 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 5145 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5236 : LDeferredCode(codegen), instr_(instr), object_(object) { 5146 : LDeferredCode(codegen), instr_(instr), object_(object) {
5237 SetExit(check_maps()); 5147 SetExit(check_maps());
5238 } 5148 }
5239 virtual void Generate() { 5149 virtual void Generate() V8_OVERRIDE {
5240 codegen()->DoDeferredInstanceMigration(instr_, object_); 5150 codegen()->DoDeferredInstanceMigration(instr_, object_);
5241 } 5151 }
5242 Label* check_maps() { return &check_maps_; } 5152 Label* check_maps() { return &check_maps_; }
5243 virtual LInstruction* instr() { return instr_; } 5153 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5244 private: 5154 private:
5245 LCheckMaps* instr_; 5155 LCheckMaps* instr_;
5246 Label check_maps_; 5156 Label check_maps_;
5247 Register object_; 5157 Register object_;
5248 }; 5158 };
5249 5159
5250 if (instr->hydrogen()->CanOmitMapChecks()) return; 5160 if (instr->hydrogen()->CanOmitMapChecks()) return;
5251 Register map_reg = scratch0(); 5161 Register map_reg = scratch0();
5252 LOperand* input = instr->value(); 5162 LOperand* input = instr->value();
5253 ASSERT(input->IsRegister()); 5163 ASSERT(input->IsRegister());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5322 __ jmp(&done); 5232 __ jmp(&done);
5323 5233
5324 __ bind(&is_smi); 5234 __ bind(&is_smi);
5325 __ ClampUint8(result_reg, scratch); 5235 __ ClampUint8(result_reg, scratch);
5326 5236
5327 __ bind(&done); 5237 __ bind(&done);
5328 } 5238 }
5329 5239
5330 5240
5331 void LCodeGen::DoAllocate(LAllocate* instr) { 5241 void LCodeGen::DoAllocate(LAllocate* instr) {
5332 class DeferredAllocate: public LDeferredCode { 5242 class DeferredAllocate V8_FINAL : public LDeferredCode {
5333 public: 5243 public:
5334 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 5244 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5335 : LDeferredCode(codegen), instr_(instr) { } 5245 : LDeferredCode(codegen), instr_(instr) { }
5336 virtual void Generate() { codegen()->DoDeferredAllocate(instr_); } 5246 virtual void Generate() V8_OVERRIDE {
5337 virtual LInstruction* instr() { return instr_; } 5247 codegen()->DoDeferredAllocate(instr_);
5248 }
5249 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5338 private: 5250 private:
5339 LAllocate* instr_; 5251 LAllocate* instr_;
5340 }; 5252 };
5341 5253
5342 DeferredAllocate* deferred = 5254 DeferredAllocate* deferred =
5343 new(zone()) DeferredAllocate(this, instr); 5255 new(zone()) DeferredAllocate(this, instr);
5344 5256
5345 Register result = ToRegister(instr->result()); 5257 Register result = ToRegister(instr->result());
5346 Register scratch = ToRegister(instr->temp1()); 5258 Register scratch = ToRegister(instr->temp1());
5347 Register scratch2 = ToRegister(instr->temp2()); 5259 Register scratch2 = ToRegister(instr->temp2());
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
5701 5613
5702 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5614 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5703 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5615 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5704 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5616 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
5705 // needed return address), even though the implementation of LAZY and EAGER is 5617 // needed return address), even though the implementation of LAZY and EAGER is
5706 // now identical. When LAZY is eventually completely folded into EAGER, remove 5618 // now identical. When LAZY is eventually completely folded into EAGER, remove
5707 // the special case below. 5619 // the special case below.
5708 if (info()->IsStub() && type == Deoptimizer::EAGER) { 5620 if (info()->IsStub() && type == Deoptimizer::EAGER) {
5709 type = Deoptimizer::LAZY; 5621 type = Deoptimizer::LAZY;
5710 } 5622 }
5623
5624 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5711 DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg)); 5625 DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg));
5712 } 5626 }
5713 5627
5714 5628
5715 void LCodeGen::DoDummyUse(LDummyUse* instr) { 5629 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5716 // Nothing to see here, move on! 5630 // Nothing to see here, move on!
5717 } 5631 }
5718 5632
5719 5633
5720 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 5634 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5721 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 5635 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5722 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 5636 __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
5723 RecordSafepointWithLazyDeopt( 5637 RecordSafepointWithLazyDeopt(
5724 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 5638 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
5725 ASSERT(instr->HasEnvironment()); 5639 ASSERT(instr->HasEnvironment());
5726 LEnvironment* env = instr->environment(); 5640 LEnvironment* env = instr->environment();
5727 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5641 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5728 } 5642 }
5729 5643
5730 5644
5731 void LCodeGen::DoStackCheck(LStackCheck* instr) { 5645 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5732 class DeferredStackCheck: public LDeferredCode { 5646 class DeferredStackCheck V8_FINAL : public LDeferredCode {
5733 public: 5647 public:
5734 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 5648 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5735 : LDeferredCode(codegen), instr_(instr) { } 5649 : LDeferredCode(codegen), instr_(instr) { }
5736 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 5650 virtual void Generate() V8_OVERRIDE {
5737 virtual LInstruction* instr() { return instr_; } 5651 codegen()->DoDeferredStackCheck(instr_);
5652 }
5653 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5738 private: 5654 private:
5739 LStackCheck* instr_; 5655 LStackCheck* instr_;
5740 }; 5656 };
5741 5657
5742 ASSERT(instr->HasEnvironment()); 5658 ASSERT(instr->HasEnvironment());
5743 LEnvironment* env = instr->environment(); 5659 LEnvironment* env = instr->environment();
5744 // There is no LLazyBailout instruction for stack-checks. We have to 5660 // There is no LLazyBailout instruction for stack-checks. We have to
5745 // prepare for lazy deoptimization explicitly here. 5661 // prepare for lazy deoptimization explicitly here.
5746 if (instr->hydrogen()->is_function_entry()) { 5662 if (instr->hydrogen()->is_function_entry()) {
5747 // Perform stack overflow check. 5663 // Perform stack overflow check.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
5879 __ Subu(scratch, result, scratch); 5795 __ Subu(scratch, result, scratch);
5880 __ lw(result, FieldMemOperand(scratch, 5796 __ lw(result, FieldMemOperand(scratch,
5881 FixedArray::kHeaderSize - kPointerSize)); 5797 FixedArray::kHeaderSize - kPointerSize));
5882 __ bind(&done); 5798 __ bind(&done);
5883 } 5799 }
5884 5800
5885 5801
5886 #undef __ 5802 #undef __
5887 5803
5888 } } // namespace v8::internal 5804 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-gap-resolver-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698