| OLD | NEW |
| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 90 |
| 91 private: | 91 private: |
| 92 MacroAssembler* masm_; | 92 MacroAssembler* masm_; |
| 93 Label patch_site_; | 93 Label patch_site_; |
| 94 #ifdef DEBUG | 94 #ifdef DEBUG |
| 95 bool info_emitted_; | 95 bool info_emitted_; |
| 96 #endif | 96 #endif |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 | 99 |
| 100 static void EmitStackCheck(MacroAssembler* masm_, | |
| 101 Register stack_limit_scratch, | |
| 102 int pointers = 0, | |
| 103 Register scratch = sp) { | |
| 104 Isolate* isolate = masm_->isolate(); | |
| 105 Label ok; | |
| 106 ASSERT(scratch.is(sp) == (pointers == 0)); | |
| 107 Heap::RootListIndex index; | |
| 108 if (pointers != 0) { | |
| 109 __ Subu(scratch, sp, Operand(pointers * kPointerSize)); | |
| 110 index = Heap::kRealStackLimitRootIndex; | |
| 111 } else { | |
| 112 index = Heap::kStackLimitRootIndex; | |
| 113 } | |
| 114 __ LoadRoot(stack_limit_scratch, index); | |
| 115 __ Branch(&ok, hs, scratch, Operand(stack_limit_scratch)); | |
| 116 PredictableCodeSizeScope predictable(masm_, 4 * Assembler::kInstrSize); | |
| 117 __ Call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET); | |
| 118 __ bind(&ok); | |
| 119 } | |
| 120 | |
| 121 | |
| 122 // Generate code for a JS function. On entry to the function the receiver | 100 // Generate code for a JS function. On entry to the function the receiver |
| 123 // and arguments have been pushed on the stack left to right. The actual | 101 // and arguments have been pushed on the stack left to right. The actual |
| 124 // argument count matches the formal parameter count expected by the | 102 // argument count matches the formal parameter count expected by the |
| 125 // function. | 103 // function. |
| 126 // | 104 // |
| 127 // The live registers are: | 105 // The live registers are: |
| 128 // o a1: the JS function object being called (i.e. ourselves) | 106 // o a1: the JS function object being called (i.e. ourselves) |
| 129 // o cp: our context | 107 // o cp: our context |
| 130 // o fp: our caller's frame pointer | 108 // o fp: our caller's frame pointer |
| 131 // o sp: stack pointer | 109 // o sp: stack pointer |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 info->set_prologue_offset(masm_->pc_offset()); | 156 info->set_prologue_offset(masm_->pc_offset()); |
| 179 __ Prologue(info->IsCodePreAgingActive()); | 157 __ Prologue(info->IsCodePreAgingActive()); |
| 180 info->AddNoFrameRange(0, masm_->pc_offset()); | 158 info->AddNoFrameRange(0, masm_->pc_offset()); |
| 181 | 159 |
| 182 { Comment cmnt(masm_, "[ Allocate locals"); | 160 { Comment cmnt(masm_, "[ Allocate locals"); |
| 183 int locals_count = info->scope()->num_stack_slots(); | 161 int locals_count = info->scope()->num_stack_slots(); |
| 184 // Generators allocate locals, if any, in context slots. | 162 // Generators allocate locals, if any, in context slots. |
| 185 ASSERT(!info->function()->is_generator() || locals_count == 0); | 163 ASSERT(!info->function()->is_generator() || locals_count == 0); |
| 186 if (locals_count > 0) { | 164 if (locals_count > 0) { |
| 187 if (locals_count >= 128) { | 165 if (locals_count >= 128) { |
| 188 EmitStackCheck(masm_, a2, locals_count, t5); | 166 Label ok; |
| 167 __ Subu(t5, sp, Operand(locals_count * kPointerSize)); |
| 168 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); |
| 169 __ Branch(&ok, hs, t5, Operand(a2)); |
| 170 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
| 171 __ bind(&ok); |
| 189 } | 172 } |
| 190 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); | 173 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); |
| 191 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32; | 174 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32; |
| 192 if (locals_count >= kMaxPushes) { | 175 if (locals_count >= kMaxPushes) { |
| 193 int loop_iterations = locals_count / kMaxPushes; | 176 int loop_iterations = locals_count / kMaxPushes; |
| 194 __ li(a2, Operand(loop_iterations)); | 177 __ li(a2, Operand(loop_iterations)); |
| 195 Label loop_header; | 178 Label loop_header; |
| 196 __ bind(&loop_header); | 179 __ bind(&loop_header); |
| 197 // Do pushes. | 180 // Do pushes. |
| 198 __ Subu(sp, sp, Operand(kMaxPushes * kPointerSize)); | 181 __ Subu(sp, sp, Operand(kMaxPushes * kPointerSize)); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 ASSERT(function->proxy()->var()->mode() == CONST || | 304 ASSERT(function->proxy()->var()->mode() == CONST || |
| 322 function->proxy()->var()->mode() == CONST_LEGACY); | 305 function->proxy()->var()->mode() == CONST_LEGACY); |
| 323 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); | 306 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); |
| 324 VisitVariableDeclaration(function); | 307 VisitVariableDeclaration(function); |
| 325 } | 308 } |
| 326 VisitDeclarations(scope()->declarations()); | 309 VisitDeclarations(scope()->declarations()); |
| 327 } | 310 } |
| 328 | 311 |
| 329 { Comment cmnt(masm_, "[ Stack check"); | 312 { Comment cmnt(masm_, "[ Stack check"); |
| 330 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); | 313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
| 331 EmitStackCheck(masm_, at); | 314 Label ok; |
| 315 __ LoadRoot(at, Heap::kStackLimitRootIndex); |
| 316 __ Branch(&ok, hs, sp, Operand(at)); |
| 317 Handle<Code> stack_check = isolate()->builtins()->StackCheck(); |
| 318 PredictableCodeSizeScope predictable(masm_, |
| 319 masm_->CallSize(stack_check, RelocInfo::CODE_TARGET)); |
| 320 __ Call(stack_check, RelocInfo::CODE_TARGET); |
| 321 __ bind(&ok); |
| 332 } | 322 } |
| 333 | 323 |
| 334 { Comment cmnt(masm_, "[ Body"); | 324 { Comment cmnt(masm_, "[ Body"); |
| 335 ASSERT(loop_depth() == 0); | 325 ASSERT(loop_depth() == 0); |
| 336 VisitStatements(function()->body()); | 326 VisitStatements(function()->body()); |
| 337 ASSERT(loop_depth() == 0); | 327 ASSERT(loop_depth() == 0); |
| 338 } | 328 } |
| 339 } | 329 } |
| 340 | 330 |
| 341 // 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 |
| (...skipping 4511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4853 Assembler::target_address_at(pc_immediate_load_address)) == | 4843 Assembler::target_address_at(pc_immediate_load_address)) == |
| 4854 reinterpret_cast<uint32_t>( | 4844 reinterpret_cast<uint32_t>( |
| 4855 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4845 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4856 return OSR_AFTER_STACK_CHECK; | 4846 return OSR_AFTER_STACK_CHECK; |
| 4857 } | 4847 } |
| 4858 | 4848 |
| 4859 | 4849 |
| 4860 } } // namespace v8::internal | 4850 } } // namespace v8::internal |
| 4861 | 4851 |
| 4862 #endif // V8_TARGET_ARCH_MIPS | 4852 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |