Chromium Code Reviews| 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 |