import types
import unittest
from test.support import (captured_stdout, requires_debug_ranges,
- requires_specialization, requires_specialization_ft,
- cpython_only)
+ requires_specialization, cpython_only)
from test.support.bytecode_helper import BytecodeTestCase
import opcode
got = self.get_disassembly(load_test, adaptive=True)
self.do_disassembly_compare(got, dis_load_test_quickened_code)
- @cpython_only
- @requires_specialization_ft
- def test_binary_specialize(self):
- binary_op_quicken = """\
- 0 RESUME_CHECK 0
-
- 1 LOAD_NAME 0 (a)
- LOAD_NAME 1 (b)
- %s
- RETURN_VALUE
-"""
- co_int = compile('a + b', "<int>", "eval")
- self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2}))
- got = self.get_disassembly(co_int, adaptive=True)
- self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)")
-
- co_unicode = compile('a + b', "<unicode>", "eval")
- self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'}))
- got = self.get_disassembly(co_unicode, adaptive=True)
- self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)")
-
@cpython_only
@requires_specialization
def test_binary_subscr_specialize(self):
got = self.get_disassembly(co, adaptive=True)
self.do_disassembly_compare(got, call_quicken)
- @cpython_only
- @requires_specialization_ft
- def test_contains_specialize(self):
- contains_op_quicken = """\
- 0 RESUME_CHECK 0
-
- 1 LOAD_NAME 0 (a)
- LOAD_NAME 1 (b)
- %s
- RETURN_VALUE
-"""
- co_dict = compile('a in b', "<dict>", "eval")
- self.code_quicken(lambda: exec(co_dict, {}, {'a': 1, 'b': {1: 5}}))
- got = self.get_disassembly(co_dict, adaptive=True)
- self.do_disassembly_compare(got, contains_op_quicken % "CONTAINS_OP_DICT 0 (in)")
-
- co_set = compile('a in b', "<set>", "eval")
- self.code_quicken(lambda: exec(co_set, {}, {'a': 1.0, 'b': {1, 2, 3}}))
- got = self.get_disassembly(co_set, adaptive=True)
- self.do_disassembly_compare(got, contains_op_quicken % "CONTAINS_OP_SET 0 (in)")
-
@cpython_only
@requires_specialization
def test_loop_quicken(self):
import threading
import types
import unittest
-from test.support import threading_helper, check_impl_detail, requires_specialization
+from test.support import (threading_helper, check_impl_detail,
+ requires_specialization, requires_specialization_ft,
+ cpython_only)
from test.support.import_helper import import_module
# Skip this module on other interpreters, it is cpython specific:
opnames = {instruction.opname for instruction in instructions}
self.assertIn(opname, opnames)
+ def assert_no_opcode(self, f, opname):
+ instructions = dis.get_instructions(f, adaptive=True)
+ opnames = {instruction.opname for instruction in instructions}
+ self.assertNotIn(opname, opnames)
+
class TestLoadSuperAttrCache(unittest.TestCase):
def test_descriptor_not_double_executed_on_spec_fail(self):
self.assertEqual(test_obj.b, 0)
+class TestSpecializer(TestBase):
+
+ @cpython_only
+ @requires_specialization_ft
+ def test_binary_op(self):
+ def f():
+ for _ in range(100):
+ a, b = 1, 2
+ c = a + b
+ self.assertEqual(c, 3)
+
+ f()
+ self.assert_specialized(f, "BINARY_OP_ADD_INT")
+ self.assert_no_opcode(f, "BINARY_OP")
+
+ def g():
+ for _ in range(100):
+ a, b = "foo", "bar"
+ c = a + b
+ self.assertEqual(c, "foobar")
+
+ g()
+ self.assert_specialized(g, "BINARY_OP_ADD_UNICODE")
+ self.assert_no_opcode(g, "BINARY_OP")
+
+ @cpython_only
+ @requires_specialization_ft
+ def test_contain_op(self):
+ def f():
+ for _ in range(100):
+ a, b = 1, {1: 2, 2: 5}
+ self.assertTrue(a in b)
+ self.assertFalse(3 in b)
+
+ f()
+ self.assert_specialized(f, "CONTAINS_OP_DICT")
+ self.assert_no_opcode(f, "CONTAINS_OP")
+
+ def g():
+ for _ in range(100):
+ a, b = 1, {1, 2}
+ self.assertTrue(a in b)
+ self.assertFalse(3 in b)
+
+ g()
+ self.assert_specialized(g, "CONTAINS_OP_SET")
+ self.assert_no_opcode(g, "CONTAINS_OP")
+
+
+
if __name__ == "__main__":
unittest.main()