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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 // derived constructors with super calls. | 251 // derived constructors with super calls. |
252 Variable* this_function_var = scope()->this_function_var(); | 252 Variable* this_function_var = scope()->this_function_var(); |
253 if (this_function_var != nullptr) { | 253 if (this_function_var != nullptr) { |
254 Comment cmnt(masm_, "[ This function"); | 254 Comment cmnt(masm_, "[ This function"); |
255 SetVar(this_function_var, a1, a2, a3); | 255 SetVar(this_function_var, a1, a2, a3); |
256 } | 256 } |
257 | 257 |
258 Variable* new_target_var = scope()->new_target_var(); | 258 Variable* new_target_var = scope()->new_target_var(); |
259 if (new_target_var != nullptr) { | 259 if (new_target_var != nullptr) { |
260 Comment cmnt(masm_, "[ new.target"); | 260 Comment cmnt(masm_, "[ new.target"); |
261 // new.target is parameter -2. | 261 |
262 int offset = 2 * kPointerSize + | 262 // Get the frame pointer for the calling frame. |
263 (info_->scope()->num_parameters() + 1) * kPointerSize; | 263 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
264 __ lw(v0, MemOperand(fp, offset)); | 264 |
| 265 // Skip the arguments adaptor frame if it exists. |
| 266 Label check_frame_marker; |
| 267 __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset)); |
| 268 __ Branch(&check_frame_marker, ne, a1, |
| 269 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 270 __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset)); |
| 271 |
| 272 // Check the marker in the calling frame. |
| 273 __ bind(&check_frame_marker); |
| 274 __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset)); |
| 275 |
| 276 Label non_construct_frame, done; |
| 277 __ Branch(&non_construct_frame, ne, a1, |
| 278 Operand(Smi::FromInt(StackFrame::CONSTRUCT))); |
| 279 |
| 280 __ lw(v0, MemOperand(a2, StandardFrameConstants::kExpressionsOffset - |
| 281 2 * kPointerSize)); |
| 282 __ Branch(&done); |
| 283 |
| 284 __ bind(&non_construct_frame); |
| 285 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| 286 __ bind(&done); |
| 287 |
265 SetVar(new_target_var, v0, a2, a3); | 288 SetVar(new_target_var, v0, a2, a3); |
266 } | 289 } |
267 | 290 |
268 ArgumentsAccessStub::HasNewTarget has_new_target = | |
269 IsSubclassConstructor(info->function()->kind()) | |
270 ? ArgumentsAccessStub::HAS_NEW_TARGET | |
271 : ArgumentsAccessStub::NO_NEW_TARGET; | |
272 | |
273 // Possibly allocate RestParameters | 291 // Possibly allocate RestParameters |
274 int rest_index; | 292 int rest_index; |
275 Variable* rest_param = scope()->rest_parameter(&rest_index); | 293 Variable* rest_param = scope()->rest_parameter(&rest_index); |
276 if (rest_param) { | 294 if (rest_param) { |
277 Comment cmnt(masm_, "[ Allocate rest parameter array"); | 295 Comment cmnt(masm_, "[ Allocate rest parameter array"); |
278 | 296 |
279 int num_parameters = info->scope()->num_parameters(); | 297 int num_parameters = info->scope()->num_parameters(); |
280 int offset = num_parameters * kPointerSize; | 298 int offset = num_parameters * kPointerSize; |
281 if (has_new_target == ArgumentsAccessStub::HAS_NEW_TARGET) { | |
282 --num_parameters; | |
283 ++rest_index; | |
284 } | |
285 | 299 |
286 __ Addu(a3, fp, | 300 __ Addu(a3, fp, |
287 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 301 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
288 __ li(a2, Operand(Smi::FromInt(num_parameters))); | 302 __ li(a2, Operand(Smi::FromInt(num_parameters))); |
289 __ li(a1, Operand(Smi::FromInt(rest_index))); | 303 __ li(a1, Operand(Smi::FromInt(rest_index))); |
290 __ li(a0, Operand(Smi::FromInt(language_mode()))); | 304 __ li(a0, Operand(Smi::FromInt(language_mode()))); |
291 __ Push(a3, a2, a1, a0); | 305 __ Push(a3, a2, a1, a0); |
292 | 306 |
293 RestParamAccessStub stub(isolate()); | 307 RestParamAccessStub stub(isolate()); |
294 __ CallStub(&stub); | 308 __ CallStub(&stub); |
(...skipping 24 matching lines...) Expand all Loading... |
319 // The stub will rewrite receiever and parameter count if the previous | 333 // The stub will rewrite receiever and parameter count if the previous |
320 // stack frame was an arguments adapter frame. | 334 // stack frame was an arguments adapter frame. |
321 ArgumentsAccessStub::Type type; | 335 ArgumentsAccessStub::Type type; |
322 if (is_strict(language_mode()) || !is_simple_parameter_list()) { | 336 if (is_strict(language_mode()) || !is_simple_parameter_list()) { |
323 type = ArgumentsAccessStub::NEW_STRICT; | 337 type = ArgumentsAccessStub::NEW_STRICT; |
324 } else if (function()->has_duplicate_parameters()) { | 338 } else if (function()->has_duplicate_parameters()) { |
325 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 339 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
326 } else { | 340 } else { |
327 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 341 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
328 } | 342 } |
329 ArgumentsAccessStub stub(isolate(), type, has_new_target); | 343 ArgumentsAccessStub stub(isolate(), type); |
330 __ CallStub(&stub); | 344 __ CallStub(&stub); |
331 | 345 |
332 SetVar(arguments, v0, a1, a2); | 346 SetVar(arguments, v0, a1, a2); |
333 } | 347 } |
334 | 348 |
335 if (FLAG_trace) { | 349 if (FLAG_trace) { |
336 __ CallRuntime(Runtime::kTraceEnter, 0); | 350 __ CallRuntime(Runtime::kTraceEnter, 0); |
337 } | 351 } |
338 | 352 |
339 // Visit the declarations and body unless there is an illegal | 353 // Visit the declarations and body unless there is an illegal |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 // Add a label for checking the size of the code used for returning. | 494 // Add a label for checking the size of the code used for returning. |
481 Label check_exit_codesize; | 495 Label check_exit_codesize; |
482 masm_->bind(&check_exit_codesize); | 496 masm_->bind(&check_exit_codesize); |
483 #endif | 497 #endif |
484 // Make sure that the constant pool is not emitted inside of the return | 498 // Make sure that the constant pool is not emitted inside of the return |
485 // sequence. | 499 // sequence. |
486 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 500 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
487 // Here we use masm_-> instead of the __ macro to avoid the code coverage | 501 // Here we use masm_-> instead of the __ macro to avoid the code coverage |
488 // tool from instrumenting as we rely on the code size here. | 502 // tool from instrumenting as we rely on the code size here. |
489 int32_t arg_count = info_->scope()->num_parameters() + 1; | 503 int32_t arg_count = info_->scope()->num_parameters() + 1; |
490 if (IsSubclassConstructor(info_->function()->kind())) { | |
491 arg_count++; | |
492 } | |
493 int32_t sp_delta = arg_count * kPointerSize; | 504 int32_t sp_delta = arg_count * kPointerSize; |
494 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 505 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); |
495 __ RecordJSReturn(); | 506 __ RecordJSReturn(); |
496 masm_->mov(sp, fp); | 507 masm_->mov(sp, fp); |
497 int no_frame_start = masm_->pc_offset(); | 508 int no_frame_start = masm_->pc_offset(); |
498 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); | 509 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); |
499 masm_->Addu(sp, sp, Operand(sp_delta)); | 510 masm_->Addu(sp, sp, Operand(sp_delta)); |
500 masm_->Jump(ra); | 511 masm_->Jump(ra); |
501 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 512 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
502 } | 513 } |
(...skipping 3770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4273 // default constructor has no arguments, so no adaptor frame means no args. | 4284 // default constructor has no arguments, so no adaptor frame means no args. |
4274 __ mov(a0, zero_reg); | 4285 __ mov(a0, zero_reg); |
4275 __ Branch(&args_set_up); | 4286 __ Branch(&args_set_up); |
4276 | 4287 |
4277 // Copy arguments from adaptor frame. | 4288 // Copy arguments from adaptor frame. |
4278 { | 4289 { |
4279 __ bind(&adaptor_frame); | 4290 __ bind(&adaptor_frame); |
4280 __ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4291 __ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
4281 __ SmiUntag(a1, a1); | 4292 __ SmiUntag(a1, a1); |
4282 | 4293 |
4283 // Subtract 1 from arguments count, for new.target. | |
4284 __ Addu(a1, a1, Operand(-1)); | |
4285 __ mov(a0, a1); | 4294 __ mov(a0, a1); |
4286 | 4295 |
4287 // Get arguments pointer in a2. | 4296 // Get arguments pointer in a2. |
4288 __ sll(at, a1, kPointerSizeLog2); | 4297 __ sll(at, a1, kPointerSizeLog2); |
4289 __ addu(a2, a2, at); | 4298 __ addu(a2, a2, at); |
4290 __ Addu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset)); | 4299 __ Addu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset)); |
4291 Label loop; | 4300 Label loop; |
4292 __ bind(&loop); | 4301 __ bind(&loop); |
4293 // Pre-decrement a2 with kPointerSize on each iteration. | 4302 // Pre-decrement a2 with kPointerSize on each iteration. |
4294 // Pre-decrement in order to skip receiver. | 4303 // Pre-decrement in order to skip receiver. |
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5553 reinterpret_cast<uint32_t>( | 5562 reinterpret_cast<uint32_t>( |
5554 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5563 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5555 return OSR_AFTER_STACK_CHECK; | 5564 return OSR_AFTER_STACK_CHECK; |
5556 } | 5565 } |
5557 | 5566 |
5558 | 5567 |
5559 } // namespace internal | 5568 } // namespace internal |
5560 } // namespace v8 | 5569 } // namespace v8 |
5561 | 5570 |
5562 #endif // V8_TARGET_ARCH_MIPS | 5571 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |