Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dffbf69

Browse files
committed
Python points-to: improve performance.
1 parent cd34e23 commit dffbf69

14 files changed

Lines changed: 391 additions & 249 deletions

File tree

python/ql/src/analysis/ContextMarginalEfficiency.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ total_size = strictcount(ControlFlowNode f, Object value, ClassObject cls, Point
2929
)
3030
and
3131
efficiency = 100.0 * total_facts / total_size
32-
select depth, total_facts, total_size, efficiency
32+
select depth, total_facts, total_size, efficiency

python/ql/src/semmle/python/Flow.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,16 @@ class CallNode extends ControlFlowNode {
465465

466466
override Call getNode() { result = super.getNode() }
467467

468+
predicate isDecoratorCall() {
469+
exists(FunctionExpr func |
470+
this.getNode() = func.getADecoratorCall()
471+
)
472+
or
473+
exists(ClassExpr cls |
474+
this.getNode() = cls.getADecoratorCall()
475+
)
476+
}
477+
468478
}
469479

470480
/** A control flow corresponding to an attribute expression, such as `value.attr` */

python/ql/src/semmle/python/objects/Callables.qll

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ abstract class CallableObjectInternal extends ObjectInternal {
3232

3333
abstract string getName();
3434

35-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
35+
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
3636
none()
3737
}
3838

39-
override predicate attributesUnknown() { none() }
39+
pragma [noinline] override predicate attributesUnknown() { none() }
4040

4141
abstract Function getScope();
4242

43-
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
43+
pragma [noinline] override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
4444

4545
abstract CallNode getACall(PointsToContext ctx);
4646

@@ -112,7 +112,7 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
112112
}
113113

114114
pragma [noinline]
115-
override predicate callResult(ObjectInternal obj, CfgOrigin origin) {
115+
override predicate callResult(ObjectInternal obj, CfgOrigin origin) {
116116
this.getScope().isProcedure() and
117117
obj = ObjectInternal::none_() and
118118
origin = CfgOrigin::fromCfgNode(this.getScope().getEntryNode())
@@ -128,15 +128,15 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
128128

129129
override boolean isDescriptor() { result = true }
130130

131-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
132-
instance.isClass() = false and
133-
value = TBoundMethod(instance, this) and origin = CfgOrigin::unknown()
134-
or
135-
any(ObjectInternal obj).binds(instance, _, this) and
136-
instance.isClass() = true and
131+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) {
132+
any(ObjectInternal obj).binds(cls, _, this) and
137133
value = this and origin = CfgOrigin::fromCfgNode(this.getOrigin())
138134
}
139135

136+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
137+
value = TBoundMethod(instance, this) and origin = CfgOrigin::unknown()
138+
}
139+
140140
override CallNode getACall(PointsToContext ctx) {
141141
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
142142
or
@@ -255,7 +255,9 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
255255

256256
override boolean isDescriptor() { result = false }
257257

258-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
258+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) { none() }
259+
260+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
259261

260262
override CallNode getACall(PointsToContext ctx) {
261263
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
@@ -339,15 +341,15 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
339341

340342
override boolean isDescriptor() { result = true }
341343

342-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
343-
instance.isClass() = false and
344-
value = TBoundMethod(instance, this) and origin = CfgOrigin::unknown()
345-
or
346-
any(ObjectInternal obj).binds(instance, _, this) and
347-
instance.isClass() = true and
344+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) {
345+
any(ObjectInternal obj).binds(cls, _, this) and
348346
value = this and origin = CfgOrigin::unknown()
349347
}
350348

349+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
350+
value = TBoundMethod(instance, this) and origin = CfgOrigin::unknown()
351+
}
352+
351353
override CallNode getACall(PointsToContext ctx) {
352354
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
353355
}
@@ -423,7 +425,9 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
423425

424426
override boolean isDescriptor() { result = false }
425427

426-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
428+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) { none() }
429+
430+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
427431

428432
override CallNode getACall(PointsToContext ctx) {
429433
PointsTo::pointsTo(result.getFunction(), ctx, this, _)

python/ql/src/semmle/python/objects/Classes.qll

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ abstract class ClassObjectInternal extends ObjectInternal {
3535

3636
override boolean isDescriptor() { result = false }
3737

38-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
38+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) { none() }
3939

40-
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
40+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
41+
42+
pragma [noinline] override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
4143
instance = this and
4244
PointsToInternal::attributeRequired(this, name) and
4345
this.lookup(name, descriptor, _) and
@@ -47,14 +49,14 @@ abstract class ClassObjectInternal extends ObjectInternal {
4749
abstract predicate lookup(string name, ObjectInternal value, CfgOrigin origin);
4850

4951
/** Approximation to descriptor protocol, skipping meta-descriptor protocol */
50-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
52+
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
5153
exists(ObjectInternal descriptor, CfgOrigin desc_origin |
5254
this.lookup(name, descriptor, desc_origin) |
5355
descriptor.isDescriptor() = false and
5456
value = descriptor and origin = desc_origin
5557
or
5658
descriptor.isDescriptor() = true and
57-
descriptor.descriptorGet(this, value, origin)
59+
descriptor.descriptorGetClass(this, value, origin)
5860
)
5961
}
6062

@@ -103,13 +105,10 @@ class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject
103105
}
104106

105107
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
106-
exists(ClassObjectInternal decl |
107-
decl = Types::getMro(this).findDeclaringClass(name) |
108-
Types::declaredAttribute(decl, name, value, origin)
109-
)
108+
Types::getMro(this).lookup(name, value, origin)
110109
}
111110

112-
override predicate attributesUnknown() { none() }
111+
pragma [noinline] override predicate attributesUnknown() { none() }
113112

114113
override predicate callResult(PointsToContext callee, ObjectInternal obj, CfgOrigin origin) {
115114
none()
@@ -166,7 +165,7 @@ class BuiltinClassObjectInternal extends ClassObjectInternal, TBuiltinClassObjec
166165
origin = CfgOrigin::unknown()
167166
}
168167

169-
override predicate attributesUnknown() { none() }
168+
pragma [noinline] override predicate attributesUnknown() { none() }
170169

171170
override predicate callResult(PointsToContext callee, ObjectInternal obj, CfgOrigin origin) {
172171
none()
@@ -226,7 +225,7 @@ class UnknownClassInternal extends ClassObjectInternal, TUnknownClass {
226225
none()
227226
}
228227

229-
override predicate attributesUnknown() { any() }
228+
pragma [noinline] override predicate attributesUnknown() { any() }
230229

231230
}
232231

@@ -274,7 +273,7 @@ class TypeInternal extends ClassObjectInternal, TType {
274273
none()
275274
}
276275

277-
override predicate attributesUnknown() { any() }
276+
pragma [noinline] override predicate attributesUnknown() { any() }
278277

279278
}
280279

@@ -311,7 +310,7 @@ class DynamicallyCreatedClass extends ClassObjectInternal, TDynamicClass {
311310
this = TDynamicClass(result, _, _)
312311
}
313312

314-
override predicate attributesUnknown() { any() }
313+
pragma [noinline] override predicate attributesUnknown() { any() }
315314

316315
override predicate introduced(ControlFlowNode node, PointsToContext context) {
317316
this = TDynamicClass(node, _, context)

python/ql/src/semmle/python/objects/Constants.qll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,19 @@ abstract class ConstantObjectInternal extends ObjectInternal {
3737
none()
3838
}
3939

40-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
40+
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
4141
none()
4242
}
4343

44-
override predicate attributesUnknown() { none() }
44+
pragma [noinline] override predicate attributesUnknown() { none() }
4545

4646
override boolean isDescriptor() { result = false }
4747

48-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
48+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) { none() }
4949

50-
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
50+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
51+
52+
pragma [noinline] override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
5153

5254
}
5355

python/ql/src/semmle/python/objects/Descriptors.qll

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class PropertyInternal extends ObjectInternal, TProperty {
4949

5050
override predicate calleeAndOffset(Function scope, int paramOffset) { none() }
5151

52-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() }
52+
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() }
5353

54-
override predicate attributesUnknown() { none() }
54+
pragma [noinline] override predicate attributesUnknown() { none() }
5555

5656
override boolean isDescriptor() { result = true }
5757

@@ -67,18 +67,22 @@ class PropertyInternal extends ObjectInternal, TProperty {
6767
)
6868
}
6969

70-
override predicate binds(ObjectInternal cls, string name, ObjectInternal descriptor) { none() }
70+
pragma [noinline] override predicate binds(ObjectInternal cls, string name, ObjectInternal descriptor) { none() }
7171

72-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
72+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) {
73+
any(ObjectInternal obj).binds(cls, _, this) and
74+
value = this and origin = CfgOrigin::fromCfgNode(this.getOrigin())
75+
}
76+
77+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
7378
/* Just give an unknown value for now. We could improve this, but it would mean
7479
* changing Contexts to account for property accesses.
7580
*/
76-
exists(AttrNode attr, ClassObjectInternal cls, string name |
81+
exists(ClassObjectInternal cls, string name |
7782
name = this.getName() and
78-
PointsToInternal::pointsTo(attr.getObject(name), _, instance, _) and
79-
instance.getClass() = cls and
83+
receiver_type(_, name, instance, cls) and
8084
cls.lookup(name, this, _) and
81-
origin = CfgOrigin::fromCfgNode(attr) and value = ObjectInternal::unknown()
85+
origin = CfgOrigin::unknown() and value = ObjectInternal::unknown()
8286
)
8387
}
8488

@@ -125,25 +129,24 @@ class ClassMethodObjectInternal extends ObjectInternal, TClassMethod {
125129

126130
override predicate calleeAndOffset(Function scope, int paramOffset) { none() }
127131

128-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() }
132+
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() }
129133

130-
override predicate attributesUnknown() { none() }
134+
pragma [noinline] override predicate attributesUnknown() { none() }
131135

132136
override boolean isDescriptor() { result = true }
133137

134-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
138+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) {
139+
value = TBoundMethod(cls, this.getFunction()) and
140+
origin = CfgOrigin::unknown()
141+
}
142+
143+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
135144
any(ObjectInternal obj).binds(instance, _, this) and
136-
exists(ObjectInternal cls |
137-
instance.isClass() = false and cls = instance.getClass()
138-
or
139-
instance.isClass() = true and cls = instance
140-
|
141-
value = TBoundMethod(cls, this.getFunction()) and
142-
origin = CfgOrigin::unknown()
143-
)
145+
value = TBoundMethod(instance.getClass(), this.getFunction()) and
146+
origin = CfgOrigin::unknown()
144147
}
145148

146-
override predicate binds(ObjectInternal cls, string name, ObjectInternal descriptor) {
149+
pragma [noinline] override predicate binds(ObjectInternal cls, string name, ObjectInternal descriptor) {
147150
descriptor = this.getFunction() and
148151
exists(ObjectInternal instance |
149152
any(ObjectInternal obj).binds(instance, name, this) |
@@ -200,18 +203,23 @@ class StaticMethodObjectInternal extends ObjectInternal, TStaticMethod {
200203
this.getFunction().calleeAndOffset(scope, paramOffset)
201204
}
202205

203-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() }
206+
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) { none() }
204207

205-
override predicate attributesUnknown() { none() }
208+
pragma [noinline] override predicate attributesUnknown() { none() }
206209

207210
override boolean isDescriptor() { result = true }
208211

209-
override predicate descriptorGet(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
212+
pragma [noinline] override predicate descriptorGetClass(ObjectInternal cls, ObjectInternal value, CfgOrigin origin) {
213+
any(ObjectInternal obj).binds(cls, _, this) and
214+
value = this.getFunction() and origin = CfgOrigin::unknown()
215+
}
216+
217+
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) {
210218
any(ObjectInternal obj).binds(instance, _, this) and
211219
value = this.getFunction() and origin = CfgOrigin::unknown()
212220
}
213221

214-
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
222+
pragma [noinline] override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) { none() }
215223

216224
override int length() { none() }
217225

0 commit comments

Comments
 (0)