PPC: First version of the new generators implementation.

Port d0ccddd032

Original commit message:
       First version of the new generators implementation.

       Behind --ignition-generators. Does not yet support Turbofan.

R=neis@chromium.org, joransiu@ca.ibm.com, mbrandy@us.ibm.com, michael_dawson@ca.ibm.com, jyan@ca.ibm.com
BUG=v8:4907
LOG=N

Review URL: https://codereview.chromium.org/1896933002

Cr-Commit-Position: refs/heads/master@{#35600}
This commit is contained in:
bjaideep 2016-04-18 15:48:05 -07:00 committed by Commit bot
parent 8292435baa
commit 9ff4a69147

View File

@ -763,68 +763,90 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// will never be used.
__ LoadP(r6, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
__ LoadWordArith(
r6, FieldMemOperand(r6, SharedFunctionInfo::kFormalParameterCountOffset));
r3, FieldMemOperand(r6, SharedFunctionInfo::kFormalParameterCountOffset));
{
Label loop, done_loop;
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
#if V8_TARGET_ARCH_PPC64
__ cmpi(r6, Operand::Zero());
__ cmpi(r3, Operand::Zero());
__ beq(&done_loop);
#else
__ SmiUntag(r6, SetRC);
__ SmiUntag(r3, SetRC);
__ beq(&done_loop, cr0);
#endif
__ mtctr(r6);
__ mtctr(r3);
__ bind(&loop);
__ push(ip);
__ bdnz(&loop);
__ bind(&done_loop);
}
// Enter a new JavaScript frame, and initialize its slots as they were when
// the generator was suspended.
FrameScope scope(masm, StackFrame::MANUAL);
__ PushStandardFrame(r7);
// Dispatch on the kind of generator object.
Label old_generator;
__ LoadP(r6, FieldMemOperand(r6, SharedFunctionInfo::kFunctionDataOffset));
__ CompareObjectType(r6, r6, r6, BYTECODE_ARRAY_TYPE);
__ bne(&old_generator);
// Restore the operand stack.
__ LoadP(r3, FieldMemOperand(r4, JSGeneratorObject::kOperandStackOffset));
__ LoadP(r6, FieldMemOperand(r3, FixedArray::kLengthOffset));
__ addi(r3, r3,
Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize));
// New-style (ignition/turbofan) generator object
{
Label loop, done_loop;
__ SmiUntag(r6, SetRC);
__ beq(&done_loop, cr0);
__ mtctr(r6);
__ bind(&loop);
__ LoadPU(ip, MemOperand(r3, kPointerSize));
__ Push(ip);
__ bdnz(&loop);
__ bind(&done_loop);
// We abuse new.target both to indicate that this is a resume call and to
// pass in the generator object. In ordinary calls, new.target is always
// undefined because generator functions are non-constructable.
__ mr(r6, r4);
__ mr(r4, r7);
__ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
__ JumpToJSEntry(ip);
}
// Reset operand stack so we don't leak.
__ LoadRoot(ip, Heap::kEmptyFixedArrayRootIndex);
__ StoreP(ip, FieldMemOperand(r4, JSGeneratorObject::kOperandStackOffset),
r0);
// Resume the generator function at the continuation.
__ LoadP(r6, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r6, FieldMemOperand(r6, SharedFunctionInfo::kCodeOffset));
__ addi(r6, r6, Operand(Code::kHeaderSize - kHeapObjectTag));
// Old-style (full-codegen) generator object
__ bind(&old_generator);
{
ConstantPoolUnavailableScope constant_pool_unavailable(masm);
if (FLAG_enable_embedded_constant_pool) {
__ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r6);
// Enter a new JavaScript frame, and initialize its slots as they were when
// the generator was suspended.
FrameScope scope(masm, StackFrame::MANUAL);
__ PushStandardFrame(r7);
// Restore the operand stack.
__ LoadP(r3, FieldMemOperand(r4, JSGeneratorObject::kOperandStackOffset));
__ LoadP(r6, FieldMemOperand(r3, FixedArray::kLengthOffset));
__ addi(r3, r3,
Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize));
{
Label loop, done_loop;
__ SmiUntag(r6, SetRC);
__ beq(&done_loop, cr0);
__ mtctr(r6);
__ bind(&loop);
__ LoadPU(ip, MemOperand(r3, kPointerSize));
__ Push(ip);
__ bdnz(&loop);
__ bind(&done_loop);
}
__ LoadP(r5, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset));
__ SmiUntag(r5);
__ add(r6, r6, r5);
__ LoadSmiLiteral(r5, Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
__ StoreP(r5, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset),
// Reset operand stack so we don't leak.
__ LoadRoot(ip, Heap::kEmptyFixedArrayRootIndex);
__ StoreP(ip, FieldMemOperand(r4, JSGeneratorObject::kOperandStackOffset),
r0);
__ mr(r3, r4); // Continuation expects generator object in r3.
__ Jump(r6);
// Resume the generator function at the continuation.
__ LoadP(r6, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r6, FieldMemOperand(r6, SharedFunctionInfo::kCodeOffset));
__ addi(r6, r6, Operand(Code::kHeaderSize - kHeapObjectTag));
{
ConstantPoolUnavailableScope constant_pool_unavailable(masm);
if (FLAG_enable_embedded_constant_pool) {
__ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r6);
}
__ LoadP(r5, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset));
__ SmiUntag(r5);
__ add(r6, r6, r5);
__ LoadSmiLiteral(r5,
Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
__ StoreP(r5, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset),
r0);
__ mr(r3, r4); // Continuation expects generator object in r3.
__ Jump(r6);
}
}
}