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_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
242 // derived constructors with super calls. | 242 // derived constructors with super calls. |
243 Variable* this_function_var = scope()->this_function_var(); | 243 Variable* this_function_var = scope()->this_function_var(); |
244 if (this_function_var != nullptr) { | 244 if (this_function_var != nullptr) { |
245 Comment cmnt(masm_, "[ This function"); | 245 Comment cmnt(masm_, "[ This function"); |
246 SetVar(this_function_var, r1, r0, r2); | 246 SetVar(this_function_var, r1, r0, r2); |
247 } | 247 } |
248 | 248 |
249 Variable* new_target_var = scope()->new_target_var(); | 249 Variable* new_target_var = scope()->new_target_var(); |
250 if (new_target_var != nullptr) { | 250 if (new_target_var != nullptr) { |
251 Comment cmnt(masm_, "[ new.target"); | 251 Comment cmnt(masm_, "[ new.target"); |
252 // new.target is parameter -2. | 252 |
253 int offset = 2 * kPointerSize + | 253 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
254 (info_->scope()->num_parameters() + 1) * kPointerSize; | 254 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
255 __ ldr(r0, MemOperand(fp, offset)); | 255 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
arv (Not doing code reviews)
2015/06/26 00:47:41
You missed a branch here.
arv (Not doing code reviews)
2015/06/26 15:15:33
Never mind... I see the trailing eq now... Somethi
| |
256 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset), eq); | |
257 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); | |
258 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); | |
259 Label non_construct_frame, done; | |
260 | |
261 __ b(ne, &non_construct_frame); | |
262 __ ldr(r0, MemOperand(r2, StandardFrameConstants::kExpressionsOffset - | |
263 2 * kPointerSize)); | |
264 __ b(&done); | |
265 | |
266 __ bind(&non_construct_frame); | |
267 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | |
268 __ bind(&done); | |
269 | |
256 SetVar(new_target_var, r0, r2, r3); | 270 SetVar(new_target_var, r0, r2, r3); |
257 } | 271 } |
258 | 272 |
259 ArgumentsAccessStub::HasNewTarget has_new_target = | |
260 IsSubclassConstructor(info->function()->kind()) | |
261 ? ArgumentsAccessStub::HAS_NEW_TARGET | |
262 : ArgumentsAccessStub::NO_NEW_TARGET; | |
263 | |
264 // Possibly allocate RestParameters | 273 // Possibly allocate RestParameters |
265 int rest_index; | 274 int rest_index; |
266 Variable* rest_param = scope()->rest_parameter(&rest_index); | 275 Variable* rest_param = scope()->rest_parameter(&rest_index); |
267 if (rest_param) { | 276 if (rest_param) { |
268 Comment cmnt(masm_, "[ Allocate rest parameter array"); | 277 Comment cmnt(masm_, "[ Allocate rest parameter array"); |
269 | 278 |
270 int num_parameters = info->scope()->num_parameters(); | 279 int num_parameters = info->scope()->num_parameters(); |
271 int offset = num_parameters * kPointerSize; | 280 int offset = num_parameters * kPointerSize; |
272 if (has_new_target == ArgumentsAccessStub::HAS_NEW_TARGET) { | |
273 --num_parameters; | |
274 ++rest_index; | |
275 } | |
276 | 281 |
277 __ add(r3, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 282 __ add(r3, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
278 __ mov(r2, Operand(Smi::FromInt(num_parameters))); | 283 __ mov(r2, Operand(Smi::FromInt(num_parameters))); |
279 __ mov(r1, Operand(Smi::FromInt(rest_index))); | 284 __ mov(r1, Operand(Smi::FromInt(rest_index))); |
280 __ mov(r0, Operand(Smi::FromInt(language_mode()))); | 285 __ mov(r0, Operand(Smi::FromInt(language_mode()))); |
281 __ Push(r3, r2, r1, r0); | 286 __ Push(r3, r2, r1, r0); |
282 | 287 |
283 RestParamAccessStub stub(isolate()); | 288 RestParamAccessStub stub(isolate()); |
284 __ CallStub(&stub); | 289 __ CallStub(&stub); |
285 | 290 |
286 SetVar(rest_param, r0, r1, r2); | 291 SetVar(rest_param, r0, r1, r2); |
287 } | 292 } |
288 | 293 |
289 Variable* arguments = scope()->arguments(); | 294 Variable* arguments = scope()->arguments(); |
290 if (arguments != NULL) { | 295 if (arguments != NULL) { |
291 // Function uses arguments object. | 296 // Function uses arguments object. |
292 Comment cmnt(masm_, "[ Allocate arguments object"); | 297 Comment cmnt(masm_, "[ Allocate arguments object"); |
293 if (!function_in_register) { | 298 if (!function_in_register) { |
294 // Load this again, if it's used by the local context below. | 299 // Load this again, if it's used by the local context below. |
295 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 300 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
296 } else { | 301 } else { |
297 __ mov(r3, r1); | 302 __ mov(r3, r1); |
298 } | 303 } |
299 // Receiver is just before the parameters on the caller's stack. | 304 // Receiver is just before the parameters on the caller's stack. |
300 int num_parameters = info->scope()->num_parameters(); | 305 int num_parameters = info->scope()->num_parameters(); |
301 int offset = num_parameters * kPointerSize; | 306 int offset = num_parameters * kPointerSize; |
302 __ add(r2, fp, | 307 |
303 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 308 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
304 __ mov(r1, Operand(Smi::FromInt(num_parameters))); | 309 __ mov(r1, Operand(Smi::FromInt(num_parameters))); |
305 __ Push(r3, r2, r1); | 310 __ Push(r3, r2, r1); |
306 | 311 |
307 // Arguments to ArgumentsAccessStub: | 312 // Arguments to ArgumentsAccessStub: |
308 // function, receiver address, parameter count. | 313 // function, receiver address, parameter count. |
309 // The stub will rewrite receiever and parameter count if the previous | 314 // The stub will rewrite receiever and parameter count if the previous |
310 // stack frame was an arguments adapter frame. | 315 // stack frame was an arguments adapter frame. |
311 ArgumentsAccessStub::Type type; | 316 ArgumentsAccessStub::Type type; |
312 if (is_strict(language_mode()) || !is_simple_parameter_list()) { | 317 if (is_strict(language_mode()) || !is_simple_parameter_list()) { |
313 type = ArgumentsAccessStub::NEW_STRICT; | 318 type = ArgumentsAccessStub::NEW_STRICT; |
314 } else if (function()->has_duplicate_parameters()) { | 319 } else if (function()->has_duplicate_parameters()) { |
315 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 320 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
316 } else { | 321 } else { |
317 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 322 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
318 } | 323 } |
319 ArgumentsAccessStub stub(isolate(), type, has_new_target); | 324 ArgumentsAccessStub stub(isolate(), type); |
320 __ CallStub(&stub); | 325 __ CallStub(&stub); |
321 | 326 |
322 SetVar(arguments, r0, r1, r2); | 327 SetVar(arguments, r0, r1, r2); |
323 } | 328 } |
324 | 329 |
325 | 330 |
326 if (FLAG_trace) { | 331 if (FLAG_trace) { |
327 __ CallRuntime(Runtime::kTraceEnter, 0); | 332 __ CallRuntime(Runtime::kTraceEnter, 0); |
328 } | 333 } |
329 | 334 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
491 | 496 |
492 #ifdef DEBUG | 497 #ifdef DEBUG |
493 // Add a label for checking the size of the code used for returning. | 498 // Add a label for checking the size of the code used for returning. |
494 Label check_exit_codesize; | 499 Label check_exit_codesize; |
495 __ bind(&check_exit_codesize); | 500 __ bind(&check_exit_codesize); |
496 #endif | 501 #endif |
497 // Make sure that the constant pool is not emitted inside of the return | 502 // Make sure that the constant pool is not emitted inside of the return |
498 // sequence. | 503 // sequence. |
499 { Assembler::BlockConstPoolScope block_const_pool(masm_); | 504 { Assembler::BlockConstPoolScope block_const_pool(masm_); |
500 int32_t arg_count = info_->scope()->num_parameters() + 1; | 505 int32_t arg_count = info_->scope()->num_parameters() + 1; |
501 if (IsSubclassConstructor(info_->function()->kind())) { | |
502 arg_count++; | |
503 } | |
504 int32_t sp_delta = arg_count * kPointerSize; | 506 int32_t sp_delta = arg_count * kPointerSize; |
505 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 507 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); |
506 // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5! | 508 // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5! |
507 PredictableCodeSizeScope predictable(masm_, -1); | 509 PredictableCodeSizeScope predictable(masm_, -1); |
508 __ RecordJSReturn(); | 510 __ RecordJSReturn(); |
509 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT); | 511 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
510 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); | 512 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_); |
511 __ add(sp, sp, Operand(sp_delta)); | 513 __ add(sp, sp, Operand(sp_delta)); |
512 __ Jump(lr); | 514 __ Jump(lr); |
513 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 515 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
(...skipping 3760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4274 __ b(eq, &adaptor_frame); | 4276 __ b(eq, &adaptor_frame); |
4275 // default constructor has no arguments, so no adaptor frame means no args. | 4277 // default constructor has no arguments, so no adaptor frame means no args. |
4276 __ mov(r0, Operand::Zero()); | 4278 __ mov(r0, Operand::Zero()); |
4277 __ b(&args_set_up); | 4279 __ b(&args_set_up); |
4278 | 4280 |
4279 // Copy arguments from adaptor frame. | 4281 // Copy arguments from adaptor frame. |
4280 { | 4282 { |
4281 __ bind(&adaptor_frame); | 4283 __ bind(&adaptor_frame); |
4282 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4284 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
4283 __ SmiUntag(r1, r1); | 4285 __ SmiUntag(r1, r1); |
4284 | |
4285 // Subtract 1 from arguments count, for new.target. | |
4286 __ sub(r1, r1, Operand(1)); | |
4287 __ mov(r0, r1); | 4286 __ mov(r0, r1); |
4288 | 4287 |
4289 // Get arguments pointer in r2. | 4288 // Get arguments pointer in r2. |
4290 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); | 4289 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); |
4291 __ add(r2, r2, Operand(StandardFrameConstants::kCallerSPOffset)); | 4290 __ add(r2, r2, Operand(StandardFrameConstants::kCallerSPOffset)); |
4292 Label loop; | 4291 Label loop; |
4293 __ bind(&loop); | 4292 __ bind(&loop); |
4294 // Pre-decrement r2 with kPointerSize on each iteration. | 4293 // Pre-decrement r2 with kPointerSize on each iteration. |
4295 // Pre-decrement in order to skip receiver. | 4294 // Pre-decrement in order to skip receiver. |
4296 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex)); | 4295 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex)); |
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5609 DCHECK(interrupt_address == | 5608 DCHECK(interrupt_address == |
5610 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5609 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5611 return OSR_AFTER_STACK_CHECK; | 5610 return OSR_AFTER_STACK_CHECK; |
5612 } | 5611 } |
5613 | 5612 |
5614 | 5613 |
5615 } // namespace internal | 5614 } // namespace internal |
5616 } // namespace v8 | 5615 } // namespace v8 |
5617 | 5616 |
5618 #endif // V8_TARGET_ARCH_ARM | 5617 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |