Commits

Mark Shannon committed 443300f Draft

Fix LOAD_SLOT_EX for register interpreter

  • Participants
  • Parent commits e7c90a9

Comments (0)

Files changed (5)

File HotPy/gen_format_code.py

     'K', 'kkK', 'r', 'rr', 'rrr', 'E', 'rrK',
     'o', 'oo', 'ro', 'rro', 'rrro', 'oK', 'rK', 'rrk',
     'rKE', 'rKKE', 'roK', 'rroK', 'rok', 'rrkkk',
-    'rE', 'rrE', 'rroE', 'rrroE', 'rokk',
+    'rE', 'rrE', 'rroE', 'rrroE', 'rokk', 'rokE',
     'rokkkE', 'rrok', 'p', 'oKKK',
     'rrooE', 'rroooE', 'rroo', 'roo',
     'oKE', 'roKE', 'rrKE', 'rroKE', 'rrrKE', 'rrrokE'

File Include/register_macros.h

 #define FORMAT_ID_roK 15
 #define FORMAT_ID_roKE 16
 #define FORMAT_ID_rok 17
-#define FORMAT_ID_rokk 18
-#define FORMAT_ID_rokkkE 19
-#define FORMAT_ID_roo 20
-#define FORMAT_ID_rr 21
-#define FORMAT_ID_rrE 22
-#define FORMAT_ID_rrK 23
-#define FORMAT_ID_rrKE 24
-#define FORMAT_ID_rrk 25
-#define FORMAT_ID_rrkkk 26
-#define FORMAT_ID_rro 27
-#define FORMAT_ID_rroE 28
-#define FORMAT_ID_rroK 29
-#define FORMAT_ID_rroKE 30
-#define FORMAT_ID_rrok 31
-#define FORMAT_ID_rroo 32
-#define FORMAT_ID_rrooE 33
-#define FORMAT_ID_rroooE 34
-#define FORMAT_ID_rrr 35
-#define FORMAT_ID_rrrKE 36
-#define FORMAT_ID_rrro 37
-#define FORMAT_ID_rrroE 38
-#define FORMAT_ID_rrrokE 39
+#define FORMAT_ID_rokE 18
+#define FORMAT_ID_rokk 19
+#define FORMAT_ID_rokkkE 20
+#define FORMAT_ID_roo 21
+#define FORMAT_ID_rr 22
+#define FORMAT_ID_rrE 23
+#define FORMAT_ID_rrK 24
+#define FORMAT_ID_rrKE 25
+#define FORMAT_ID_rrk 26
+#define FORMAT_ID_rrkkk 27
+#define FORMAT_ID_rro 28
+#define FORMAT_ID_rroE 29
+#define FORMAT_ID_rroK 30
+#define FORMAT_ID_rroKE 31
+#define FORMAT_ID_rrok 32
+#define FORMAT_ID_rroo 33
+#define FORMAT_ID_rrooE 34
+#define FORMAT_ID_rroooE 35
+#define FORMAT_ID_rrr 36
+#define FORMAT_ID_rrrKE 37
+#define FORMAT_ID_rrro 38
+#define FORMAT_ID_rrroE 39
+#define FORMAT_ID_rrrokE 40
 
 #define FORMAT_E \
     int e0; \
     k0 = (instruction_word >> 24); \
     assert(consistent_format(next_instr[-1] & 255, "rok"))
 
+#define FORMAT_rokE \
+    int r0, r1, k0, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    r1 = (instruction_word >> 16) & 255; \
+    k0 = (instruction_word >> 24); \
+    instruction_word = *next_instr++; \
+    e0 = instruction_word & ((1 << 16)-1); \
+    assert(consistent_format(next_instr[-2] & 255, "rokE"))
+
 #define FORMAT_rokk \
     int r0, r1, k0, k1; \
     r0 = (instruction_word >> 8) & 255; \

File Include/register_write_functions.h

 }
 
 static void
+write_rokE(HotPyOptimiser *x, int op, int k0, int exit)
+{
+    int r0 = pop_as_register(x, 0);
+    int out0;
+    assert(k0 >= 0);
+    assert(exit >= 0);
+    flush_stack(x);
+    out0 = choose_register(x);
+    assert(consistent_format(op, "rokE"));
+    write_word_1111(x, op, r0, out0, k0);
+    write_word_22(x, exit, 0);
+    push_register(x, out0);
+}
+
+static void
 write_rokk(HotPyOptimiser *x, int op, int k0, int k1)
 {
     int r0 = pop_as_register(x, 0);
 }
 
 void
+print_rokE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_rokE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s r%d o%d k%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, k0, e0);
+}
+
+void
 print_rokk(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 static uint32_t *
+defuses_for_rokE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_rokE;
+    *uses++ = r0;
+    *defs++ = r1;
+    (void)k0;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
 defuses_for_rokk(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+relabel_uses_rokE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_uses_rokk(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
+relabel_defs_rokE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 16) & 255; \
+    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_defs_rokk(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static HotPyContext *
+get_exit_context_rokE(uint32_t *instr, PyObject *exits)
+{
+    uint32_t instruction_word = *instr++;
+    int e0;
+    PyObject *exit;
+    instruction_word = *instr++;
+    e0 = instruction_word & ((1 << 16)-1); \
+    exit = PyTuple_GetItem(exits, e0);
+    return ((HotPyExitObject *)exit)->exit_context;
+}
+
+static HotPyContext *
 get_exit_context_rokk(uint32_t *instr, PyObject *exits)
 {
    return NULL;

File Python/register_interpreter.c

             FAST_DISPATCH();
 
         TARGET(LOAD_SLOT_EX)
-            FORMAT_rok;
+            FORMAT_rokE;
             PyObject *obj = registers[r0];
             PyObject *val = ((PyObject**)obj)[k0];
             if (val != NULL) {
                     def++;
                 }
                 PyErr_SetString(PyExc_AttributeError, def->name);
-                goto on_error;
+                exit = GETEXIT(e0);
+                goto error_with_exit;
             }
 
         TARGET(STORE_SLOT)

File Python/trace_recorder_register.c

         case POP_STACK_TO_REGISTER:
             print_o(out, &code);
             break;
-        case LOAD_SLOT: case LOAD_SLOT_EX:
+        case LOAD_SLOT:
             print_rok(out, &code);
             break;
+        case LOAD_SLOT_EX:
+            print_rokE(out, &code);
+            break;
         case STORE_TO_GLOBALS:
             print_rrK(out, &code);
             break;
         case TUPLE_SET_ITEM: case LIST_SET_ITEM: case STORE_SLOT:
         case DESCRIPTOR_GET: case GET_CLASS_ATTR: case HAS_CLASS_ATTR:
         case SUB_TYPE: case NEW_FUNCTION: case POP_STACK_TO_REGISTER:
-        case LOAD_SLOT: case LOAD_SLOT_EX: case RETURN_VALUE: case GEN_CLEAR:
+        case LOAD_SLOT: case RETURN_VALUE: case GEN_CLEAR:
         case EXIT_IF_FALSE: case EXIT_IF_TRUE: case EXIT_IF_NOT_BOOL_OR_INT:
         case MATERIALISE_FRAME:
             assert(length_via_format_matches(op, 1));
         case HAS_SPECIAL: case BUILD_SLICE: case OVERRIDES:
         case VALUE_FROM_OBJECT_DICT_OR_EXIT_CONST:
         case STORE_TO_GLOBALS: case SET_IN_OBJECT_DICT_CONST:
-        case FAST_LOAD_GLOBAL:
+        case FAST_LOAD_GLOBAL: case LOAD_SLOT_EX:
             assert(length_via_format_matches(op, 2));
             out[0] = instr[0];
             out[1] = instr[1];
         case TUPLE_SET_ITEM: case LIST_SET_ITEM: case STORE_SLOT:
         case DESCRIPTOR_GET: case GET_CLASS_ATTR: case HAS_CLASS_ATTR:
         case SUB_TYPE: case NEW_FUNCTION: case POP_STACK_TO_REGISTER:
-        case LOAD_SLOT: case LOAD_SLOT_EX: case RETURN_VALUE: case GEN_CLEAR:
+        case LOAD_SLOT: case RETURN_VALUE: case GEN_CLEAR:
         case EXIT_IF_FALSE: case EXIT_IF_TRUE: case EXIT_IF_NOT_BOOL_OR_INT:
         case MATERIALISE_FRAME:
             assert(length_via_format_matches(op, 1));
         case HAS_SPECIAL: case BUILD_SLICE: case OVERRIDES:
         case VALUE_FROM_OBJECT_DICT_OR_EXIT_CONST:
         case STORE_TO_GLOBALS: case SET_IN_OBJECT_DICT_CONST:
-        case FAST_LOAD_GLOBAL:
+        case FAST_LOAD_GLOBAL: case LOAD_SLOT_EX:
             assert(length_via_format_matches(op, 2));
             instr += 2;
             break;
 static HotPyContext *
 load_member(HotPyOptimiser *x, PyMemberDescrObject *desc)
 {
+    HotPyTraceRecorder *opt = (HotPyTraceRecorder *)x;
     PyMemberDef *def = desc->d_member;
     int slot = def->offset/sizeof(PyObject*);
-    assert("TO DO -- exit" && 0);
+    HotPyContext *context = NULL;
     assert(slot < (1 << 8));
     assert(def->offset % sizeof(PyObject*) == 0);
     if (def->type == T_OBJECT) {
         write_rok(x, LOAD_SLOT, slot);
     }
     else if (def->type == T_OBJECT_EX) {
-        write_rok(x, LOAD_SLOT_EX, slot);
+        int e;
+        context = HotPyContext_New();
+        e = new_exit(opt, context);
+        if (e < 0)
+            return NULL;
+        write_rokE(x, LOAD_SLOT_EX, slot, e);
     }
     else {
         /* Don't support int/float slots yet */
         abort();
     }
     CONSISTENT(x);
-    return NULL;
+    return context;
 }
 
 static HotPyContext *
         return defuses_for_rokkkE(instr, defs, uses);
     case POP_STACK_TO_REGISTER:
         return defuses_for_o(instr, defs, uses);
-    case LOAD_SLOT: case LOAD_SLOT_EX:
+    case LOAD_SLOT:
         return defuses_for_rok(instr, defs, uses);
+    case LOAD_SLOT_EX:
+        return defuses_for_rokE(instr, defs, uses);
     case STORE_TO_GLOBALS:
         return defuses_for_rrK(instr, defs, uses);
     case RETURN_VALUE:
         return relabel_uses_rokkkE(instr, relabel_uses_table);
     case POP_STACK_TO_REGISTER:
         return relabel_uses_o(instr, relabel_uses_table);
-    case LOAD_SLOT: case LOAD_SLOT_EX:
+    case LOAD_SLOT:
         return relabel_uses_rok(instr, relabel_uses_table);
+    case LOAD_SLOT_EX:
+        return relabel_uses_rokE(instr, relabel_uses_table);
     case STORE_TO_GLOBALS:
         return relabel_uses_rrK(instr, relabel_uses_table);
     case RETURN_VALUE:
         return relabel_defs_rokkkE(instr, relabel_defs_table);
     case POP_STACK_TO_REGISTER:
         return relabel_defs_o(instr, relabel_defs_table);
-    case LOAD_SLOT: case LOAD_SLOT_EX:
+    case LOAD_SLOT:
         return relabel_defs_rok(instr, relabel_defs_table);
+    case LOAD_SLOT_EX:
+        return relabel_defs_rokE(instr, relabel_defs_table);
     case STORE_TO_GLOBALS:
         return relabel_defs_rrK(instr, relabel_defs_table);
     case RETURN_VALUE:
         return get_exit_context_rokkkE(instr, exits);
     case POP_STACK_TO_REGISTER:
         return get_exit_context_o(instr, exits);
-    case LOAD_SLOT: case LOAD_SLOT_EX:
+    case LOAD_SLOT:
         return get_exit_context_rok(instr, exits);
+    case LOAD_SLOT_EX:
+        return get_exit_context_rokE(instr, exits);
     case STORE_TO_GLOBALS:
         return get_exit_context_rrK(instr, exits);
     case RETURN_VALUE: