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:
parent
8292435baa
commit
9ff4a69147
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user