Ver código fonte

improve f-string performance

blueloveTH 2 anos atrás
pai
commit
9af3434f06
6 arquivos alterados com 19 adições e 7 exclusões
  1. 1 1
      include/pocketpy/opcodes.h
  2. 0 1
      include/pocketpy/str.h
  3. 3 0
      include/pocketpy/vm.h
  4. 13 4
      src/ceval.cpp
  5. 1 1
      src/expr.cpp
  6. 1 0
      src/vm.cpp

+ 1 - 1
include/pocketpy/opcodes.h

@@ -90,7 +90,7 @@ OPCODE(LOOP_CONTINUE)
 OPCODE(LOOP_BREAK)
 OPCODE(GOTO)
 /**************************/
-OPCODE(EVAL_CONST)
+OPCODE(FSTRING_EVAL)
 OPCODE(REPR)
 OPCODE(CALL)
 OPCODE(CALL_TP)

+ 0 - 1
include/pocketpy/str.h

@@ -225,7 +225,6 @@ const StrName __class__ = StrName::get("__class__");
 
 const StrName pk_id_add = StrName::get("add");
 const StrName pk_id_set = StrName::get("set");
-const StrName pk_id_eval = StrName::get("eval");
 
 #define DEF_SNAME(name) const static StrName name(#name)
 

+ 3 - 0
include/pocketpy/vm.h

@@ -136,6 +136,9 @@ public:
     PyObject* _last_exception;  // last exception
     PyObject* _curr_class;      // current class being defined
 
+    // cached code objects for FSTRING_EVAL
+    std::map<std::string_view, CodeObject_> _cached_codes;
+
 #if PK_ENABLE_CEVAL_CALLBACK
     void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr;
 #endif

+ 13 - 4
src/ceval.cpp

@@ -568,10 +568,19 @@ __NEXT_STEP:;
         frame->jump_abs_break(index);
     } DISPATCH();
     /*****************************************/
-    TARGET(EVAL_CONST){
-        PyObject* _0 = builtins->attr(pk_id_eval);
-        PyObject* _1 = co_consts[byte.arg];
-        PUSH(call(_0, _1));
+    TARGET(FSTRING_EVAL){
+        PyObject* _0 = co_consts[byte.arg];
+        std::string_view string = CAST(Str&, _0).sv();
+        auto it = _cached_codes.find(string);
+        CodeObject_ code;
+        if(it == _cached_codes.end()){
+            code = vm->compile(string, "<eval>", EVAL_MODE, true);
+            _cached_codes[string] = code;
+        }else{
+            code = it->second;
+        }
+        _0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
+        PUSH(_0);
     } DISPATCH();
     TARGET(REPR)
         TOP() = py_repr(TOP());

+ 1 - 1
src/expr.cpp

@@ -392,7 +392,7 @@ namespace pkpy{
             }
         }else{
             int index = ctx->add_const(py_var(ctx->vm, expr));
-            ctx->emit_(OP_EVAL_CONST, index, line);
+            ctx->emit_(OP_FSTRING_EVAL, index, line);
         }
         if(repr){
             ctx->emit_(OP_REPR, BC_NOARG, line);

+ 1 - 0
src/vm.cpp

@@ -1199,6 +1199,7 @@ void ManagedHeap::mark() {
     if(vm->_last_exception) PK_OBJ_MARK(vm->_last_exception);
     if(vm->_curr_class) PK_OBJ_MARK(vm->_curr_class);
     if(vm->_c.error != nullptr) PK_OBJ_MARK(vm->_c.error);
+    for(auto [_, co]: vm->_cached_codes) co->_gc_mark();
 }
 
 Str obj_type_name(VM *vm, Type type){