Skip to content

Commit 91f8c46

Browse files
committed
Pass __class__ cell via a temporary __classcell__ attribute
Avoids false sharing of cells between contexts and gets closer to CPython's behavior which also uses __classcell__.
1 parent b111cda commit 91f8c46

File tree

7 files changed

+25
-94
lines changed

7 files changed

+25
-94
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import static com.oracle.graal.python.nodes.BuiltinNames.TYPE;
5353
import static com.oracle.graal.python.nodes.BuiltinNames.ZIP;
5454
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASICSIZE__;
55+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASSCELL__;
5556
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICTOFFSET__;
5657
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
5758
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ITEMSIZE__;
@@ -2001,8 +2002,11 @@ Object type(VirtualFrame frame, LazyPythonClass cls, String name, PTuple bases,
20012002
@Cached GetLazyClassNode getMetaclassNode,
20022003
@Cached("create(__NEW__)") LookupInheritedAttributeNode getNewFuncNode,
20032004
@Cached("create(__INIT_SUBCLASS__)") GetAttributeNode getInitSubclassNode,
2005+
@Cached HashingStorageNodes.GetItemNode getClasscellNode,
2006+
@Cached HashingStorageNodes.DelItemNode delClasscellNode,
20042007
@Cached CallNode callInitSubclassNode,
20052008
@Cached CallNode callNewFuncNode) {
2009+
20062010
// Determine the proper metatype to deal with this
20072011
LazyPythonClass metaclass = calculate_metaclass(frame, cls, bases, getMetaclassNode);
20082012
if (metaclass != cls) {
@@ -2038,6 +2042,17 @@ Object type(VirtualFrame frame, LazyPythonClass cls, String name, PTuple bases,
20382042
}
20392043
}
20402044

2045+
// set __class__ cell contents
2046+
Object classcell = getClasscellNode.execute(frame, namespace.getDictStorage(), __CLASSCELL__);
2047+
if (classcell != null) {
2048+
if (classcell instanceof PCell) {
2049+
((PCell) classcell).setRef(newType);
2050+
} else {
2051+
raise(TypeError, "__classcell__ must be a cell");
2052+
}
2053+
delClasscellNode.execute(frame, namespace, namespace.getDictStorage(), __CLASSCELL__);
2054+
}
2055+
20412056
return newType;
20422057
} catch (PException e) {
20432058
throw e;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/NodeFactory.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import com.oracle.graal.python.nodes.attributes.SetAttributeNode;
3737
import com.oracle.graal.python.nodes.call.PythonCallNode;
3838
import com.oracle.graal.python.nodes.cell.ReadLocalCellNode;
39-
import com.oracle.graal.python.nodes.cell.WriteCellVarNode;
4039
import com.oracle.graal.python.nodes.cell.WriteLocalCellNode;
4140
import com.oracle.graal.python.nodes.classes.ReadClassAttributeNode;
4241
import com.oracle.graal.python.nodes.control.BlockNode;
@@ -448,10 +447,6 @@ public ExpressionNode createReadClassAttributeNode(String identifier, FrameSlot
448447
return ReadClassAttributeNode.create(identifier, cellSlot, isFreeVar);
449448
}
450449

451-
public StatementNode createWriteCellVar(ExpressionNode readNode, FunctionRootNode funcRootNode, String identifier) {
452-
return WriteCellVarNode.create(readNode, funcRootNode, identifier);
453-
}
454-
455450
public ExpressionNode createReadLocalCell(FrameSlot slot, boolean isFreeVar) {
456451
assert slot != null;
457452
return ReadLocalCellNode.create(slot, isFreeVar);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialAttributeNames.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -45,6 +45,7 @@ public abstract class SpecialAttributeNames {
4545
public static final String __DEFAULTS__ = "__defaults__";
4646
public static final String __CODE__ = "__code__";
4747
public static final String __GLOBALS__ = "__globals__";
48+
public static final String __CLASSCELL__ = "__classcell__";
4849
public static final String __CLOSURE__ = "__closure__";
4950
public static final String __ANNOTATIONS__ = "__annotations__";
5051
public static final String __KWDEFAULTS__ = "__kwdefaults__";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/cell/WriteCellVarNode.java

Lines changed: 0 additions & 72 deletions
This file was deleted.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/FunctionRootNode.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -54,7 +54,6 @@
5454
*/
5555
public class FunctionRootNode extends PClosureFunctionRootNode {
5656
@CompilationFinal private ContextReference<PythonContext> contextRef;
57-
private final PCell[] cells;
5857
private final ExecutionCellSlots executionCellSlots;
5958
private final String functionName;
6059
private final SourceSection sourceSection;
@@ -72,7 +71,6 @@ public FunctionRootNode(PythonLanguage language, SourceSection sourceSection, St
7271
ExecutionCellSlots executionCellSlots, Signature signature) {
7372
super(language, frameDescriptor, executionCellSlots, signature);
7473
this.executionCellSlots = executionCellSlots;
75-
this.cells = new PCell[this.cellVarSlots.length];
7674

7775
this.sourceSection = sourceSection;
7876
assert sourceSection != null;
@@ -93,10 +91,6 @@ public String getName() {
9391
return functionName;
9492
}
9593

96-
public PCell[] getCells() {
97-
return cells;
98-
}
99-
10094
public FrameSlot[] getCellVarSlots() {
10195
return cellVarSlots;
10296
}
@@ -123,7 +117,6 @@ private void initializeCellVars(Frame frame) {
123117

124118
// store the cell as a local var
125119
frame.setObject(frameSlot, cell);
126-
this.cells[i] = cell;
127120
}
128121
}
129122

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/sst/FactorySSTVisitor.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
import static com.oracle.graal.python.nodes.BuiltinNames.__BUILD_CLASS__;
4545
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ANNOTATIONS__;
46+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASSCELL__;
4647
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASS__;
4748
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DOC__;
4849
import static com.oracle.graal.python.nodes.frame.FrameSlotIDs.TEMP_LOCAL_PREFIX;
@@ -388,7 +389,7 @@ public PNode visit(ClassSSTNode node) {
388389
classBody.assignSourceSection(createSourceSection(classBodyStart, node.body.endOffset));
389390

390391
delta = delta + (classScope.hasAnnotations() ? 1 : 0);
391-
StatementNode[] classStatements = new StatementNode[2 + delta];
392+
StatementNode[] classStatements = new StatementNode[3 + delta];
392393
// ClassStatemtns look like:
393394
// [0] ClassDefinitionPrologueNode
394395
classStatements[0] = new ClassDefinitionPrologueNode(qualifiedName);
@@ -401,8 +402,11 @@ public PNode visit(ClassSSTNode node) {
401402
if (classScope.hasAnnotations()) {
402403
classStatements[delta] = scopeEnvironment.findVariable(__ANNOTATIONS__).makeWriteNode(nodeFactory.createDictLiteral());
403404
}
404-
// [last] class body statements
405+
// [last - 1] class body statements
405406
classStatements[1 + delta] = classBody;
407+
// [last] assign __class__ cell to __classcell__
408+
classStatements[2 + delta] = scopeEnvironment.findVariable(__CLASSCELL__).makeWriteNode(
409+
nodeFactory.createReadLocal(scopeEnvironment.getCurrentScope().getFrameDescriptor().findFrameSlot(__CLASS__)));
406410

407411
SourceSection nodeSourceSection = createSourceSection(node.startOffset, node.endOffset);
408412
StatementNode body = nodeFactory.createBlock(classStatements);
@@ -439,11 +443,7 @@ public PNode visit(ClassSSTNode node) {
439443

440444
ReadNode read = scopeEnvironment.findVariable(node.name);
441445

442-
ReadNode tempLocal = makeTempLocalVariable();
443-
ExpressionNode newClass = ((ExpressionNode) tempLocal).withSideEffect(
444-
nodeFactory.createBlock(tempLocal.makeWriteNode(classDef),
445-
nodeFactory.createWriteCellVar((ExpressionNode) tempLocal, classBodyRoot, __CLASS__)));
446-
PNode result = read.makeWriteNode(newClass);
446+
PNode result = read.makeWriteNode(classDef);
447447
result.assignSourceSection(nodeSourceSection);
448448
return result;
449449
}

mx.graalpython/copyrights/overrides

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallD
389389
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java,zippy.copyright
390390
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/PythonCallNode.java,zippy.copyright
391391
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/cell/ReadLocalCellNode.java,zippy.copyright
392-
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/cell/WriteCellVarNode.java,zippy.copyright
393392
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/cell/WriteLocalCellNode.java,zippy.copyright
394393
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/control/BaseBlockNode.java,zippy.copyright
395394
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/control/BlockNode.java,zippy.copyright

0 commit comments

Comments
 (0)