[vm/bytecode] Add context IDs to disambiguate accesses to distinct contexts

This CL adds context ID operand to AllocateContext, CloneContext,
LoadContextVar and StoreContextVar bytecode instructions.
The context ID will be used to create distinct Slots and disambiguate
accesses to context objects corresponding to different scopes.

Change-Id: I98850ab763017b71c1dcacfccaffc085bd850e00
Reviewed-on: https://dart-review.googlesource.com/c/84681
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
This commit is contained in:
Alexander Markov 2018-11-17 00:35:30 +00:00 committed by commit-bot@chromium.org
parent 81d899ac30
commit a9abc64613
11 changed files with 473 additions and 435 deletions

View file

@ -317,8 +317,8 @@ class BytecodeAssembler {
emitWord(_encode0(Opcode.kStoreContextParent));
}
void emitStoreContextVar(int rd) {
emitWord(_encodeD(Opcode.kStoreContextVar, rd));
void emitStoreContextVar(int ra, int rd) {
emitWord(_encodeAD(Opcode.kStoreContextVar, ra, rd));
}
void emitLoadFieldTOS(int rd) {
@ -333,8 +333,8 @@ class BytecodeAssembler {
emitWord(_encode0(Opcode.kLoadContextParent));
}
void emitLoadContextVar(int rd) {
emitWord(_encodeD(Opcode.kLoadContextVar, rd));
void emitLoadContextVar(int ra, int rd) {
emitWord(_encodeAD(Opcode.kLoadContextVar, ra, rd));
}
void emitBooleanNegateTOS() {
@ -359,12 +359,12 @@ class BytecodeAssembler {
emitWord(_encodeA(Opcode.kSetFrame, ra));
}
void emitAllocateContext(int rd) {
emitWord(_encodeD(Opcode.kAllocateContext, rd));
void emitAllocateContext(int ra, int rd) {
emitWord(_encodeAD(Opcode.kAllocateContext, ra, rd));
}
void emitCloneContext(int rd) {
emitWord(_encodeD(Opcode.kCloneContext, rd));
void emitCloneContext(int ra, int rd) {
emitWord(_encodeAD(Opcode.kCloneContext, ra, rd));
}
void emitMoveSpecial(SpecialIndex ra, int rx) {

View file

@ -173,17 +173,17 @@ const Map<Opcode, Format> BytecodeFormats = const {
Opcode.kCreateArrayTOS: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kAllocateContext: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kCloneContext: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kLoadContextParent: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kStoreContextParent: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kLoadContextVar: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kStoreContextVar: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kPushConstant: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kPushNull: const Format(
@ -347,6 +347,9 @@ const int localVariableIndexLimit = 1 << 15;
// Captured variables are referenced using 16-bit unsigned operands.
const int capturedVariableIndexLimit = 1 << 16;
// Context IDs are referenced using 8-bit unsigned operands.
const int contextIdLimit = 1 << 8;
// Base class for exceptions thrown when certain limit of bytecode
// format is exceeded.
abstract class BytecodeLimitExceededException {}

View file

@ -634,7 +634,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
void _genLoadVar(VariableDeclaration v, {int currentContextLevel}) {
if (locals.isCaptured(v)) {
_genPushContextForVariable(v, currentContextLevel: currentContextLevel);
asm.emitLoadContextVar(locals.getVarIndexInContext(v));
asm.emitLoadContextVar(
locals.getVarContextId(v), locals.getVarIndexInContext(v));
} else {
asm.emitPush(locals.getVarIndexInFrame(v));
}
@ -650,7 +651,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
// If variable is captured, context should be pushed before value.
void _genStoreVar(VariableDeclaration variable) {
if (locals.isCaptured(variable)) {
asm.emitStoreContextVar(locals.getVarIndexInContext(variable));
asm.emitStoreContextVar(locals.getVarContextId(variable),
locals.getVarIndexInContext(variable));
} else {
asm.emitPopLocal(locals.getVarIndexInFrame(variable));
}
@ -1426,7 +1428,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
void _allocateContextIfNeeded() {
final int contextSize = locals.currentContextSize;
if (contextSize > 0) {
asm.emitAllocateContext(contextSize);
asm.emitAllocateContext(locals.currentContextId, contextSize);
if (locals.currentContextLevel > 0) {
_genDupTOS(locals.scratchVarIndexInFrame);
@ -2466,7 +2468,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
if (locals.currentContextSize > 0) {
asm.emitPush(locals.contextVarIndexInFrame);
asm.emitCloneContext(locals.currentContextSize);
asm.emitCloneContext(
locals.currentContextId, locals.currentContextSize);
asm.emitPopLocal(locals.contextVarIndexInFrame);
}
@ -2849,11 +2852,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
} else {
asm.emitPushNull();
}
if (isCaptured) {
asm.emitStoreContextVar(locals.getVarIndexInContext(node));
} else {
asm.emitPopLocal(locals.getVarIndexInFrame(node));
}
_genStoreVar(node);
}
}

View file

@ -63,6 +63,7 @@ class LocalVariables {
int get currentContextSize => _currentScope.contextSize;
int get currentContextLevel => _currentScope.contextLevel;
int get currentContextId => _currentScope.contextId;
int get contextLevelAtEntry =>
_currentFrame.contextLevelAtEntry ??
@ -74,6 +75,12 @@ class LocalVariables {
return v.scope.contextLevel;
}
int getVarContextId(VariableDeclaration variable) {
final v = _getVarDesc(variable);
assert(v.isCaptured);
return v.scope.contextId;
}
int get closureVarIndexInFrame => getVarIndexInFrame(_currentFrame
.closureVar ??
(throw 'Closure variable is not declared in ${_currentFrame.function}'));
@ -257,6 +264,7 @@ class Scope {
int contextUsed = 0;
int contextSize = 0;
int contextLevel;
int contextId;
Scope(this.parent, this.frame, this.loopDepth);
@ -699,6 +707,7 @@ class _Allocator extends RecursiveVisitor<Null> {
Scope _currentScope;
Frame _currentFrame;
int _contextIdCounter = 0;
_Allocator(this.locals);
@ -738,6 +747,7 @@ class _Allocator extends RecursiveVisitor<Null> {
assert(_currentScope.contextOwner == null);
assert(_currentScope.contextLevel == null);
assert(_currentScope.contextId == null);
final int parentContextLevel =
_currentScope.parent != null ? _currentScope.parent.contextLevel : -1;
@ -763,8 +773,13 @@ class _Allocator extends RecursiveVisitor<Null> {
if (_currentScope.contextOwner == _currentScope) {
_currentScope.contextLevel = parentContextLevel + 1;
_currentScope.contextId = _contextIdCounter++;
if (_currentScope.contextId >= contextIdLimit) {
throw new ContextIdOverflowException();
}
} else {
_currentScope.contextLevel = _currentScope.contextOwner.contextLevel;
_currentScope.contextId = _currentScope.contextOwner.contextId;
}
} else {
_currentScope.contextLevel = parentContextLevel;
@ -1147,3 +1162,5 @@ class _Allocator extends RecursiveVisitor<Null> {
class LocalVariableIndexOverflowException
extends BytecodeLimitExceededException {}
class ContextIdOverflowException extends BytecodeLimitExceededException {}

File diff suppressed because it is too large Load diff

View file

@ -187,11 +187,11 @@ Bytecode (version: stable) {
Entry 5
CheckStack 0
CheckFunctionTypeArgs 2, r0
AllocateContext 1
AllocateContext 0, 1
PopLocal r1
Push r1
Push FP[-5]
StoreContextVar 0
StoreContextVar 0, 0
Allocate CP#31
StoreLocal r4
Push r4
@ -290,7 +290,7 @@ Closure CP#12 {
Push r3
PushInt 0
Push r1
LoadContextVar 0
LoadContextVar 0, 0
LoadTypeArgumentsField CP#15
PushNull
InstantiateType CP#14
@ -298,7 +298,7 @@ Closure CP#12 {
Push r3
PushInt 1
Push r1
LoadContextVar 0
LoadContextVar 0, 0
LoadTypeArgumentsField CP#15
PushNull
InstantiateType CP#16
@ -345,7 +345,7 @@ Closure CP#12 {
IndirectStaticCall 1, CP#25
Drop1
Push r1
LoadContextVar 0
LoadContextVar 0, 0
LoadTypeArgumentsField CP#15
Push r0
InstantiateTypeArgumentsTOS 0, CP#27
@ -385,7 +385,7 @@ L2:
StoreLocal r4
Push r4
Push r1
LoadContextVar 0
LoadContextVar 0, 0
LoadTypeArgumentsField CP#15
StoreFieldTOS CP#32
Push r4
@ -437,7 +437,7 @@ L2:
StoreLocal r4
Push r4
Push r1
LoadContextVar 0
LoadContextVar 0, 0
LoadTypeArgumentsField CP#15
StoreFieldTOS CP#32
Push r4
@ -506,19 +506,19 @@ ConstantPool {
Bytecode (version: stable) {
Entry 5
CheckStack 0
AllocateContext 4
AllocateContext 0, 4
PopLocal r0
Push r0
Push FP[-5]
StoreContextVar 0
StoreContextVar 0, 0
Push r0
PushInt 1
StoreContextVar 1
StoreContextVar 0, 1
PushInt 2
PopLocal r2
Push r0
PushInt 3
StoreContextVar 2
StoreContextVar 0, 2
Allocate CP#10
StoreLocal r4
Push r4
@ -550,18 +550,18 @@ Bytecode (version: stable) {
IndirectStaticCall 1, CP#7
Drop1
Push r0
LoadContextVar 2
LoadContextVar 0, 2
PushConstant CP#27
IndirectStaticCall 1, CP#7
Drop1
Push r0
LoadContextVar 1
LoadContextVar 0, 1
PushConstant CP#28
IndirectStaticCall 1, CP#7
Drop1
Push r0
PushInt 42
StoreContextVar 3
StoreContextVar 0, 3
Allocate CP#10
StoreLocal r3
Push r3
@ -631,19 +631,19 @@ Closure CP#6 {
LoadContextParent
Push r0
LoadContextParent
LoadContextVar 1
LoadContextVar 0, 1
PushInt 2
AddInt
StoreContextVar 2
StoreContextVar 0, 2
Push r0
Push r0
LoadContextParent
LoadContextVar 0
LoadContextVar 0, 0
InstanceCall 1, CP#8
Push r0
LoadContextVar 0
LoadContextVar 1, 0
AddInt
StoreContextVar 1
StoreContextVar 1, 1
PushNull
ReturnTOS
@ -655,7 +655,7 @@ Closure CP#0 {
Push FP[-6]
LoadFieldTOS CP#1
PopLocal r0
AllocateContext 2
AllocateContext 1, 2
StoreLocal r1
Push r1
Push r0
@ -663,7 +663,7 @@ Closure CP#0 {
PopLocal r0
Push r0
Push FP[-5]
StoreContextVar 0
StoreContextVar 1, 0
Push FP[-5]
PushConstant CP#3
PushNull
@ -674,19 +674,19 @@ Closure CP#0 {
Push r0
LoadContextParent
Push r0
LoadContextVar 0
LoadContextVar 1, 0
PushInt 1
AddInt
StoreContextVar 1
StoreContextVar 0, 1
Push r0
LoadContextParent
LoadContextVar 1
LoadContextVar 0, 1
PushInt 5
CompareIntGt
JumpIfFalse L1
Push r0
PushInt 4
StoreContextVar 1
StoreContextVar 1, 1
Allocate CP#10
StoreLocal r2
Push r2
@ -709,7 +709,7 @@ Closure CP#0 {
InstanceCall 1, CP#20
Drop1
Push r0
LoadContextVar 1
LoadContextVar 1, 1
PushConstant CP#21
IndirectStaticCall 1, CP#7
Drop1
@ -726,9 +726,9 @@ Closure CP#29 {
LoadFieldTOS CP#1
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
Push r0
LoadContextVar 3
LoadContextVar 0, 3
InstanceCall 2, CP#30
Drop1
PushNull
@ -792,11 +792,11 @@ ConstantPool {
Bytecode (version: stable) {
Entry 5
CheckStack 0
AllocateContext 1
AllocateContext 0, 1
PopLocal r0
Push r0
PushInt 0
StoreContextVar 0
StoreContextVar 0, 0
PushConstant CP#0
StoreLocal r3
Push r3
@ -815,7 +815,7 @@ Bytecode (version: stable) {
PushConstant CP#3
IndirectStaticCall 2, CP#1
PopLocal r4
AllocateContext 1
AllocateContext 1, 1
StoreLocal r1
Push r1
Push r0
@ -823,11 +823,11 @@ Bytecode (version: stable) {
PopLocal r0
Push r0
PushInt 0
StoreContextVar 0
StoreContextVar 1, 0
L2:
CheckStack 1
Push r0
LoadContextVar 0
LoadContextVar 1, 0
PushInt 10
CompareIntLt
JumpIfFalse L1
@ -872,15 +872,15 @@ L2:
InstanceCall 2, CP#24
Drop1
Push r0
CloneContext 1
CloneContext 1, 1
PopLocal r0
Push r0
Push r0
LoadContextVar 0
LoadContextVar 1, 0
PushInt 1
AddInt
StoreLocal r3
StoreContextVar 0
StoreContextVar 1, 0
Push r3
Drop1
Jump L2
@ -928,10 +928,10 @@ Closure CP#4 {
LoadFieldTOS CP#5
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 1, 0
Push r0
LoadContextParent
LoadContextVar 0
LoadContextVar 0, 0
AddInt
ReturnTOS
@ -954,9 +954,9 @@ Closure CP#19 {
Push FP[-5]
Push r0
LoadContextParent
LoadContextVar 0
LoadContextVar 0, 0
AddInt
StoreContextVar 0
StoreContextVar 1, 0
PushNull
ReturnTOS
@ -984,12 +984,12 @@ L2:
Push r2
InstanceCall 1, CP#2
JumpIfFalse L1
AllocateContext 1
AllocateContext 0, 1
PopLocal r0
Push r0
Push r2
InstanceCall 1, CP#3
StoreContextVar 0
StoreContextVar 0, 0
Allocate CP#8
StoreLocal r4
Push r4
@ -1012,7 +1012,7 @@ L2:
InstanceCall 1, CP#18
Drop1
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#19
IndirectStaticCall 1, CP#0
Drop1
@ -1054,10 +1054,10 @@ Closure CP#4 {
PopLocal r0
Push r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushInt 1
AddInt
StoreContextVar 0
StoreContextVar 0, 0
PushNull
ReturnTOS
@ -1095,11 +1095,11 @@ ConstantPool {
Bytecode (version: stable) {
Entry 3
CheckStack 0
AllocateContext 1
AllocateContext 0, 1
PopLocal r0
Push r0
Push FP[-5]
StoreContextVar 0
StoreContextVar 0, 0
Push FP[-5]
PushConstant CP#0
Push FP[-6]
@ -1155,7 +1155,7 @@ Closure CP#4 {
LoadFieldTOS CP#5
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
ReturnTOS
}
@ -1167,11 +1167,11 @@ Closure CP#4 {
Bytecode (version: stable) {
Entry 4
CheckStack 0
AllocateContext 1
AllocateContext 0, 1
PopLocal r0
Push r0
PushInt 5
StoreContextVar 0
StoreContextVar 0, 0
Allocate CP#7
StoreLocal r3
Push r3
@ -1195,7 +1195,7 @@ Bytecode (version: stable) {
InstanceCall 2, CP#18
Drop1
Push r0
LoadContextVar 0
LoadContextVar 0, 0
ReturnTOS
}
ConstantPool {
@ -1234,10 +1234,10 @@ Closure CP#0 {
Drop1
Push r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
Push FP[-5]
AddInt
StoreContextVar 0
StoreContextVar 0, 0
PushNull
ReturnTOS

View file

@ -229,17 +229,17 @@ ConstantPool {
Bytecode (version: stable) {
Entry 7
CheckStack 0
AllocateContext 3
AllocateContext 0, 3
PopLocal r0
Push r0
PushInt 1
StoreContextVar 0
StoreContextVar 0, 0
Push r0
PopLocal r2
Try #0 start:
Push r0
PushInt 2
StoreContextVar 1
StoreContextVar 0, 1
Allocate CP#9
StoreLocal r5
Push r5
@ -262,7 +262,7 @@ Try #0 start:
InstanceCall 1, CP#19
Drop1
Push r0
LoadContextVar 1
LoadContextVar 0, 1
PushConstant CP#20
IndirectStaticCall 1, CP#4
Drop1
@ -278,7 +278,7 @@ Try #0 handler:
PopLocal r4
Push r0
Push r3
StoreContextVar 2
StoreContextVar 0, 2
PushNull
PushInt 4
CreateArrayTOS
@ -298,7 +298,7 @@ Try #0 handler:
Push r5
PushInt 3
Push r0
LoadContextVar 2
LoadContextVar 0, 2
StoreIndexedTOS
PushConstant CP#23
IndirectStaticCall 1, CP#4
@ -397,13 +397,13 @@ Try #0 handler:
Push r2
PopLocal r4
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#7
IndirectStaticCall 1, CP#4
Drop1
Push r0
PushInt 3
StoreContextVar 1
StoreContextVar 0, 1
Jump L1
L1:
PushNull
@ -457,7 +457,7 @@ Try #0 handler:
Push r5
PushInt 3
Push r0
LoadContextVar 2
LoadContextVar 0, 2
StoreIndexedTOS
PushConstant CP#33
IndirectStaticCall 1, CP#4
@ -692,13 +692,13 @@ ConstantPool {
Bytecode (version: stable) {
Entry 9
CheckStack 0
AllocateContext 2
AllocateContext 0, 2
PopLocal r0
Push r0
Push FP[-5]
StoreContextVar 0
StoreContextVar 0, 0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PopLocal r2
Push r2
PushInt 1
@ -719,7 +719,7 @@ Try #0 start:
Drop1
Push r0
PushInt 3
StoreContextVar 1
StoreContextVar 0, 1
Push r0
PopLocal r5
Try #1 start:
@ -852,12 +852,12 @@ Closure CP#8 {
LoadFieldTOS CP#9
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#11
IndirectStaticCall 1, CP#4
Drop1
Push r0
LoadContextVar 1
LoadContextVar 0, 1
PushConstant CP#12
IndirectStaticCall 1, CP#4
Drop1
@ -905,11 +905,11 @@ Closure CP#8 {
Bytecode (version: stable) {
Entry 6
CheckStack 0
AllocateContext 1
AllocateContext 0, 1
PopLocal r0
Push r0
PushInt 11
StoreContextVar 0
StoreContextVar 0, 0
PushNull
PopLocal r2
Push r0
@ -942,7 +942,7 @@ Try #0 handler:
MoveSpecial exception, r3
MoveSpecial stackTrace, r4
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#26
IndirectStaticCall 1, CP#3
Drop1
@ -956,7 +956,7 @@ L1:
Push r3
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#28
IndirectStaticCall 1, CP#3
Drop1
@ -1011,7 +1011,7 @@ Closure CP#0 {
LoadFieldTOS CP#1
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#4
IndirectStaticCall 1, CP#3
Drop1
@ -1046,7 +1046,7 @@ Try #1 handler:
MoveSpecial exception, r4
MoveSpecial stackTrace, r5
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#10
IndirectStaticCall 1, CP#3
Drop1
@ -1057,7 +1057,7 @@ L2:
Push r4
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#11
IndirectStaticCall 1, CP#3
Drop1
@ -1082,7 +1082,7 @@ Try #2 handler:
MoveSpecial exception, r4
MoveSpecial stackTrace, r5
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#13
IndirectStaticCall 1, CP#3
Drop1
@ -1093,7 +1093,7 @@ L3:
Push r4
PopLocal r0
Push r0
LoadContextVar 0
LoadContextVar 0, 0
PushConstant CP#14
IndirectStaticCall 1, CP#3
Drop1

View file

@ -34,7 +34,8 @@ T* PutIfAbsent(Thread* thread,
return array->At(index);
}
LocalVariable* CompilerState::GetDummyCapturedVariable(intptr_t index) {
LocalVariable* CompilerState::GetDummyCapturedVariable(intptr_t context_id,
intptr_t index) {
return PutIfAbsent<LocalVariable>(
thread(), &dummy_captured_vars_, index, [&]() {
Zone* const Z = thread()->zone();
@ -52,6 +53,7 @@ LocalVariable* CompilerState::GetDummyCapturedVariable(intptr_t index) {
}
const GrowableArray<LocalVariable*>& CompilerState::GetDummyContextVariables(
intptr_t context_id,
intptr_t num_context_variables) {
return PutIfAbsent<LocalScope>(
thread(), &dummy_scopes_, num_context_variables,
@ -63,7 +65,7 @@ const GrowableArray<LocalVariable*>& CompilerState::GetDummyContextVariables(
scope->set_context_level(0);
for (intptr_t i = 0; i < num_context_variables; i++) {
LocalVariable* var = GetDummyCapturedVariable(i);
LocalVariable* var = GetDummyCapturedVariable(context_id, i);
scope->AddVariable(var);
scope->AddContextVariable(var);
}

View file

@ -87,16 +87,20 @@ class CompilerState : public StackResource {
void set_slot_cache(SlotCache* cache) { slot_cache_ = cache; }
// Create a dummy list of local variables representing a context object
// with the given number of captured variables.
// with the given number of captured variables and given ID.
//
// Used during bytecode to IL translation because AllocateContext and
// CloneContext IL instructions need a list of local varaibles and bytecode
// does not record this information.
//
// TODO(vegorov): create context classes for distinct context IDs and
// populate them with slots without creating variables.
const GrowableArray<LocalVariable*>& GetDummyContextVariables(
intptr_t context_id,
intptr_t num_context_variables);
// Create a dummy LocalVariable that represents a captured local variable
// at the given index.
// at the given index in the context with given ID.
//
// Used during bytecode to IL translation because StoreInstanceField and
// LoadField IL instructions need Slot, which can only be created from a
@ -104,7 +108,9 @@ class CompilerState : public StackResource {
//
// This function returns the same variable when it is called with the
// same index.
LocalVariable* GetDummyCapturedVariable(intptr_t index);
//
// TODO(vegorov): disambiguate slots for different context IDs.
LocalVariable* GetDummyCapturedVariable(intptr_t context_id, intptr_t index);
private:
CHA cha_;

View file

@ -781,8 +781,11 @@ void BytecodeFlowGraphBuilder::BuildAllocateContext() {
UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
}
const intptr_t context_id = DecodeOperandA().value();
const intptr_t num_context_vars = DecodeOperandD().value();
auto& context_variables = CompilerState::Current().GetDummyContextVariables(
DecodeOperandD().value());
context_id, num_context_vars);
code_ += B->AllocateContext(context_variables);
}
@ -792,8 +795,11 @@ void BytecodeFlowGraphBuilder::BuildCloneContext() {
}
LoadStackSlots(1);
const intptr_t context_id = DecodeOperandA().value();
const intptr_t num_context_vars = DecodeOperandD().value();
auto& context_variables = CompilerState::Current().GetDummyContextVariables(
DecodeOperandD().value());
context_id, num_context_vars);
CloneContextInstr* clone_instruction = new (Z) CloneContextInstr(
TokenPosition::kNoSource, Pop(), context_variables, B->GetNextDeoptId());
code_ <<= clone_instruction;
@ -885,12 +891,11 @@ void BytecodeFlowGraphBuilder::BuildStoreContextVar() {
}
LoadStackSlots(2);
Operand var_index = DecodeOperandD();
const intptr_t context_id = DecodeOperandA().value();
const intptr_t var_index = DecodeOperandD().value();
// TODO(alexmarkov) provide context_id in bytecode to disambiguate variables
// in different contexts
auto var =
CompilerState::Current().GetDummyCapturedVariable(var_index.value());
CompilerState::Current().GetDummyCapturedVariable(context_id, var_index);
code_ += B->StoreInstanceField(
position_, Slot::GetContextVariableSlotFor(thread(), *var));
}
@ -901,12 +906,11 @@ void BytecodeFlowGraphBuilder::BuildLoadContextVar() {
}
LoadStackSlots(1);
Operand var_index = DecodeOperandD();
const intptr_t context_id = DecodeOperandA().value();
const intptr_t var_index = DecodeOperandD().value();
// TODO(alexmarkov) provide context_id in bytecode to disambiguate variables
// in different contexts
auto var =
CompilerState::Current().GetDummyCapturedVariable(var_index.value());
CompilerState::Current().GetDummyCapturedVariable(context_id, var_index);
code_ += B->LoadNativeField(Slot::GetContextVariableSlotFor(thread(), *var));
}

View file

@ -155,13 +155,18 @@ namespace dart {
//
// Allocate array of length SP[0] with type arguments SP[-1].
//
// - AllocateContext D
// - AllocateContext A, D
//
// Allocate Context object assuming for D context variables.
// Allocate Context object holding D context variables.
// A is a static ID of the context. Static ID of a context may be used to
// disambiguate accesses to different context objects.
// Context objects with the same ID should have the same number of
// context variables.
//
// - CloneContext D
// - CloneContext A, D
//
// Clone Context object stored in TOS assuming it has D context variables.
// Clone Context object SP[0] holding D context variables.
// A is a static ID of the context. Cloned context has the same ID.
//
// - LoadContextParent
//
@ -171,13 +176,15 @@ namespace dart {
//
// Store context SP[0] into `parent` field of context SP[-1].
//
// - LoadContextVar D
// - LoadContextVar A, D
//
// Load value from context SP[0] at index D.
// A is a static ID of the context.
//
// - StoreContextVar D
// - StoreContextVar A, D
//
// Store value SP[0] into context SP[-1] at index D.
// A is a static ID of the context.
//
// - PushConstant D
//