OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 4385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4396 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 4396 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
4397 | 4397 |
4398 // Restore callee-saved registers and return. | 4398 // Restore callee-saved registers and return. |
4399 #ifdef DEBUG | 4399 #ifdef DEBUG |
4400 if (FLAG_debug_code) __ mov(lr, Operand(pc)); | 4400 if (FLAG_debug_code) __ mov(lr, Operand(pc)); |
4401 #endif | 4401 #endif |
4402 __ ldm(ia_w, sp, kCalleeSaved | pc.bit()); | 4402 __ ldm(ia_w, sp, kCalleeSaved | pc.bit()); |
4403 } | 4403 } |
4404 | 4404 |
4405 | 4405 |
4406 void ArgumentsAccessStub::Generate(MacroAssembler* masm) { | 4406 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { |
4407 // ----------- S t a t e ------------- | |
4408 // -- r0: formal number of parameters for the calling function | |
4409 // -- r1: key (if value access) | |
4410 // -- lr: return address | |
4411 // ----------------------------------- | |
4412 | |
4413 // If we're reading an element we need to check that the key is a smi. | |
4414 Label slow; | |
4415 if (type_ == READ_ELEMENT) { | |
4416 __ tst(r1, Operand(kSmiTagMask)); | |
4417 __ b(ne, &slow); | |
4418 } | |
4419 | |
4420 // Check if the calling frame is an arguments adaptor frame. | 4407 // Check if the calling frame is an arguments adaptor frame. |
4421 // r0: formal number of parameters | |
4422 // r1: key (if access) | |
4423 Label adaptor; | 4408 Label adaptor; |
4424 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 4409 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
4425 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); | 4410 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
4426 __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); | 4411 __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
4427 if (type_ == NEW_OBJECT) { | 4412 __ b(eq, &adaptor); |
4428 __ b(ne, &slow); | |
4429 } else { | |
4430 __ b(eq, &adaptor); | |
4431 } | |
4432 | 4413 |
4433 static const int kParamDisplacement = | 4414 // Nothing to do: The formal number of parameters has already been |
4434 StandardFrameConstants::kCallerSPOffset - kPointerSize; | 4415 // passed in register r0 by calling function. Just return it. |
| 4416 __ mov(pc, lr); |
4435 | 4417 |
4436 if (type_ == READ_LENGTH) { | 4418 // Arguments adaptor case: Read the arguments length from the |
4437 // Nothing to do: The formal number of parameters has already been | 4419 // adaptor frame and return it. |
4438 // passed in register r0 by calling function. Just return it. | |
4439 __ mov(pc, lr); | |
4440 } else if (type_ == READ_ELEMENT) { | |
4441 // Check index against formal parameter count. Use unsigned comparison to | |
4442 // get the negative check for free. | |
4443 // r0: formal number of parameters | |
4444 // r1: index | |
4445 __ cmp(r1, r0); | |
4446 __ b(cs, &slow); | |
4447 | |
4448 // Read the argument from the current frame and return it. | |
4449 __ sub(r3, r0, r1); | |
4450 __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
4451 __ ldr(r0, MemOperand(r3, kParamDisplacement)); | |
4452 __ mov(pc, lr); | |
4453 } else { | |
4454 ASSERT(type_ == NEW_OBJECT); | |
4455 // Do nothing here. | |
4456 } | |
4457 | |
4458 // An arguments adaptor frame is present. Find the length or the actual | |
4459 // argument in the calling frame. | |
4460 // r0: formal number of parameters | |
4461 // r1: key | |
4462 // r2: adaptor frame pointer | |
4463 __ bind(&adaptor); | 4420 __ bind(&adaptor); |
4464 // Read the arguments length from the adaptor frame. This is the result if | |
4465 // only accessing the length, otherwise it is used in accessing the value | |
4466 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4421 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
4467 | 4422 __ mov(pc, lr); |
4468 if (type_ == READ_LENGTH) { | |
4469 // Return the length in r0. | |
4470 __ mov(pc, lr); | |
4471 } else if (type_ == READ_ELEMENT) { | |
4472 // Check index against actual arguments count. Use unsigned comparison to | |
4473 // get the negative check for free. | |
4474 // r0: actual number of parameter | |
4475 // r1: index | |
4476 // r2: adaptor frame point | |
4477 __ cmp(r1, r0); | |
4478 __ b(cs, &slow); | |
4479 | |
4480 // Read the argument from the adaptor frame and return it. | |
4481 __ sub(r3, r0, r1); | |
4482 __ add(r3, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
4483 __ ldr(r0, MemOperand(r3, kParamDisplacement)); | |
4484 __ mov(pc, lr); | |
4485 } else { | |
4486 ASSERT(type_ == NEW_OBJECT); | |
4487 // Patch the arguments.length and the parameters pointer. | |
4488 __ str(r0, MemOperand(sp, 0 * kPointerSize)); | |
4489 __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
4490 __ add(r3, r3, Operand(kParamDisplacement + 1 * kPointerSize)); | |
4491 __ str(r3, MemOperand(sp, 1 * kPointerSize)); | |
4492 __ bind(&slow); | |
4493 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); | |
4494 } | |
4495 | |
4496 // Return to the calling function. | |
4497 if (type_ == READ_ELEMENT) { | |
4498 __ bind(&slow); | |
4499 __ push(r1); | |
4500 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); | |
4501 } | |
4502 } | 4423 } |
4503 | 4424 |
4504 | 4425 |
| 4426 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
| 4427 // The displacement is the offset of the last parameter (if any) |
| 4428 // relative to the frame pointer. |
| 4429 static const int kDisplacement = |
| 4430 StandardFrameConstants::kCallerSPOffset - kPointerSize; |
| 4431 |
| 4432 // Check that the key is a smi. |
| 4433 Label slow; |
| 4434 __ tst(r1, Operand(kSmiTagMask)); |
| 4435 __ b(ne, &slow); |
| 4436 |
| 4437 // Check if the calling frame is an arguments adaptor frame. |
| 4438 Label adaptor; |
| 4439 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 4440 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
| 4441 __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
| 4442 __ b(eq, &adaptor); |
| 4443 |
| 4444 // Check index against formal parameters count limit passed in |
| 4445 // through register eax. Use unsigned comparison to get negative |
| 4446 // check for free. |
| 4447 __ cmp(r1, r0); |
| 4448 __ b(cs, &slow); |
| 4449 |
| 4450 // Read the argument from the stack and return it. |
| 4451 __ sub(r3, r0, r1); |
| 4452 __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 4453 __ ldr(r0, MemOperand(r3, kDisplacement)); |
| 4454 __ mov(pc, lr); |
| 4455 |
| 4456 // Arguments adaptor case: Check index against actual arguments |
| 4457 // limit found in the arguments adaptor frame. Use unsigned |
| 4458 // comparison to get negative check for free. |
| 4459 __ bind(&adaptor); |
| 4460 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4461 __ cmp(r1, r0); |
| 4462 __ b(cs, &slow); |
| 4463 |
| 4464 // Read the argument from the adaptor frame and return it. |
| 4465 __ sub(r3, r0, r1); |
| 4466 __ add(r3, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 4467 __ ldr(r0, MemOperand(r3, kDisplacement)); |
| 4468 __ mov(pc, lr); |
| 4469 |
| 4470 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
| 4471 // by calling the runtime system. |
| 4472 __ bind(&slow); |
| 4473 __ push(r1); |
| 4474 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); |
| 4475 } |
| 4476 |
| 4477 |
| 4478 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
| 4479 // Check if the calling frame is an arguments adaptor frame. |
| 4480 Label runtime; |
| 4481 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 4482 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
| 4483 __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
| 4484 __ b(ne, &runtime); |
| 4485 |
| 4486 // Patch the arguments.length and the parameters pointer. |
| 4487 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 4488 __ str(r0, MemOperand(sp, 0 * kPointerSize)); |
| 4489 __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 4490 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 4491 __ str(r3, MemOperand(sp, 1 * kPointerSize)); |
| 4492 |
| 4493 // Do the runtime call to allocate the arguments object. |
| 4494 __ bind(&runtime); |
| 4495 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); |
| 4496 } |
| 4497 |
| 4498 |
4505 void ArmCodeGenerator::SetReferenceProperty(CodeGenerator* cgen, | 4499 void ArmCodeGenerator::SetReferenceProperty(CodeGenerator* cgen, |
4506 Reference* ref, | 4500 Reference* ref, |
4507 Expression* key) { | 4501 Expression* key) { |
4508 ASSERT(!ref->is_illegal()); | 4502 ASSERT(!ref->is_illegal()); |
4509 MacroAssembler* masm = cgen->masm(); | 4503 MacroAssembler* masm = cgen->masm(); |
4510 | 4504 |
4511 if (ref->type() == Reference::NAMED) { | 4505 if (ref->type() == Reference::NAMED) { |
4512 // Compute the name of the property. | 4506 // Compute the name of the property. |
4513 Literal* literal = key->AsLiteral(); | 4507 Literal* literal = key->AsLiteral(); |
4514 Handle<String> name(String::cast(*literal->handle())); | 4508 Handle<String> name(String::cast(*literal->handle())); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4573 bool is_eval) { | 4567 bool is_eval) { |
4574 Handle<Code> code = ArmCodeGenerator::MakeCode(fun, script, is_eval); | 4568 Handle<Code> code = ArmCodeGenerator::MakeCode(fun, script, is_eval); |
4575 if (!code.is_null()) { | 4569 if (!code.is_null()) { |
4576 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 4570 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
4577 } | 4571 } |
4578 return code; | 4572 return code; |
4579 } | 4573 } |
4580 | 4574 |
4581 | 4575 |
4582 } } // namespace v8::internal | 4576 } } // namespace v8::internal |
OLD | NEW |