Просмотр исходного кода

up

Update vm.h

up

up

Update common.h
blueloveTH 3 лет назад
Родитель
Сommit
8eaa80da2e
11 измененных файлов с 73 добавлено и 97 удалено
  1. 1 1
      profile.sh
  2. 3 3
      src/ceval.h
  3. 4 4
      src/codeobject.h
  4. 3 2
      src/common.h
  5. 1 1
      src/compiler.h
  6. 32 1
      src/memory.h
  7. 4 4
      src/obj.h
  8. 3 3
      src/parser.h
  9. 14 35
      src/safestl.h
  10. 4 31
      src/str.h
  11. 4 12
      src/vm.h

+ 1 - 1
profile.sh

@@ -1,6 +1,6 @@
 g++ -o pocketpy src/main.cpp --std=c++17 -pg -O2 -fno-rtti
 
-./pocketpy benchmarks/loop_1.py
+./pocketpy benchmarks/fib.py
 
 gprof pocketpy gmon.out > gprof.txt
 

+ 3 - 3
src/ceval.h

@@ -223,9 +223,9 @@ PyVar VM::run_frame(Frame* frame){
         case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); continue;
         case OP_GOTO: {
             StrName label = frame->co->names[byte.arg].first;
-            int* target = frame->co->labels.try_get(label);
-            if(target == nullptr) _error("KeyError", "label " + label.str().escape(true) + " not found");
-            frame->jump_abs_safe(*target);
+            auto it = frame->co->labels.find(label);
+            if(it == frame->co->labels.end()) _error("KeyError", "label " + label.str().escape(true) + " not found");
+            frame->jump_abs_safe(it->second);
         } continue;
         case OP_GET_ITER: {
             PyVar obj = frame->pop_value(this);

+ 4 - 4
src/codeobject.h

@@ -61,20 +61,20 @@ struct CodeObject {
     std::vector<Bytecode> codes;
     pkpy::List consts;
     std::vector<std::pair<StrName, NameScope>> names;
-    pkpy::HashMap<StrName, int> global_names;
+    std::map<StrName, int> global_names;
     std::vector<CodeBlock> blocks = { CodeBlock{NO_BLOCK, -1} };
-    pkpy::HashMap<StrName, int> labels;
+    std::map<StrName, int> labels;
 
     void optimize(VM* vm);
 
     bool add_label(StrName label){
-        if(labels.contains(label)) return false;
+        if(labels.count(label)) return false;
         labels[label] = codes.size();
         return true;
     }
 
     int add_name(StrName name, NameScope scope){
-        if(scope == NAME_LOCAL && global_names.contains(name)) scope = NAME_GLOBAL;
+        if(scope == NAME_LOCAL && global_names.count(name)) scope = NAME_GLOBAL;
         auto p = std::make_pair(name, scope);
         for(int i=0; i<names.size(); i++){
             if(names[i] == p) return i;

+ 3 - 2
src/common.h

@@ -28,10 +28,11 @@
 // namespace fs = std::filesystem;
 
 #define EMH_EXT 1
-#include "hash_table8.hpp"
+#define EMH_FIND_HIT 1
+#include "hash_table5.hpp"
 namespace pkpy {
 	template<typename... Args>
-	using HashMap = emhash8::HashMap<Args...>;
+	using HashMap = emhash5::HashMap<Args...>;
 }
 
 #ifdef POCKETPY_H

+ 1 - 1
src/compiler.h

@@ -23,7 +23,7 @@ class Compiler {
     int lexing_count = 0;
     bool used = false;
     VM* vm;
-    pkpy::HashMap<TokenIndex, GrammarRule> rules;
+    std::map<TokenIndex, GrammarRule> rules;
 
     CodeObject_ co() const{ return codes.top(); }
     CompileMode mode() const{ return parser->src->mode; }

+ 32 - 1
src/memory.h

@@ -115,4 +115,35 @@ namespace pkpy{
 static_assert(sizeof(i64) == sizeof(pkpy::shared_ptr<PyObject>));
 static_assert(sizeof(f64) == sizeof(pkpy::shared_ptr<PyObject>));
 static_assert(std::numeric_limits<float>::is_iec559);
-static_assert(std::numeric_limits<double>::is_iec559);
+static_assert(std::numeric_limits<double>::is_iec559);
+
+template<typename T, int __Bucket, int __BucketSize=32>
+struct SmallArrayPool {
+    std::deque<T*> buckets[__Bucket+1];
+
+    T* alloc(int n){
+        if(n == 0) return nullptr;
+        if(n > __Bucket || buckets[n].empty()){
+            return new T[n];
+        }else{
+            T* p = buckets[n].back();
+            buckets[n].pop_back();
+            return p;
+        }
+    }
+
+    void dealloc(T* p, int n){
+        if(n == 0) return;
+        if(n > __Bucket){
+            delete[] p;
+        }else{
+            buckets[n].push_back(p);
+        }
+    }
+
+    ~SmallArrayPool(){
+        for(int i=1; i<=__Bucket; i++){
+            for(auto p: buckets[i]) delete[] p;
+        }
+    }
+};

+ 4 - 4
src/obj.h

@@ -23,10 +23,10 @@ struct NativeFunc {
 struct Function {
     Str name;
     CodeObject_ code;
-    std::vector<Str> args;
-    Str starred_arg;                // empty if no *arg
+    std::vector<StrName> args;
+    StrName starred_arg;                // empty if no *arg
     pkpy::NameDict kwargs;          // empty if no k=v
-    std::vector<Str> kwargs_order;
+    std::vector<StrName> kwargs_order;
 
     // runtime settings
     PyVar _module;
@@ -35,7 +35,7 @@ struct Function {
     bool has_name(const Str& val) const {
         bool _0 = std::find(args.begin(), args.end(), val) != args.end();
         bool _1 = starred_arg == val;
-        bool _2 = kwargs.find(val) != kwargs.end();
+        bool _2 = kwargs.contains(val);
         return _0 || _1 || _2;
     }
 };

+ 3 - 3
src/parser.h

@@ -38,8 +38,8 @@ constexpr TokenIndex TK(const char* const token) {
 const TokenIndex kTokenKwBegin = TK("class");
 const TokenIndex kTokenKwEnd = TK("raise");
 
-const pkpy::HashMap<std::string_view, TokenIndex> kTokenKwMap = [](){
-    pkpy::HashMap<std::string_view, TokenIndex> map;
+const std::map<std::string_view, TokenIndex> kTokenKwMap = [](){
+    std::map<std::string_view, TokenIndex> map;
     for(int k=kTokenKwBegin; k<=kTokenKwEnd; k++) map[kTokens[k]] = k;
     return map;
 }();
@@ -231,7 +231,7 @@ struct Parser {
             return 0;
         }
 
-        if(kTokenKwMap.contains(name)){
+        if(kTokenKwMap.count(name)){
             if(name == "not"){
                 if(strncmp(curr_char, " in", 3) == 0){
                     curr_char += 3;

+ 14 - 35
src/safestl.h

@@ -33,42 +33,21 @@ public:
     using std::vector<PyVar>::vector;
 };
 
-typedef pkpy::HashMap<StrName, PyVar> NameDict;
 
 }
 
 namespace pkpy {
-    const int kMaxPoolSize = 10;
-    static THREAD_LOCAL std::vector<PyVar*>* _args_pool = new std::vector<PyVar*>[kMaxPoolSize];
+    typedef HashMap<StrName, PyVar> NameDict;
 
     class Args {
+        static THREAD_LOCAL SmallArrayPool<PyVar, 10> _pool;
+
         PyVar* _args;
         int _size;
 
-        void _alloc(int n){
-            if(n == 0){
-                this->_args = nullptr;
-                this->_size = 0;
-                return;
-            }
-            if(n >= kMaxPoolSize || _args_pool[n].empty()){
-                this->_args = new PyVar[n];
-                this->_size = n;
-            }else{
-                this->_args = _args_pool[n].back();
-                this->_size = n;
-                _args_pool[n].pop_back();
-            }
-        }
-
-        void _dealloc(){
-            if(_size == 0 || _args == nullptr) return;
-            if(_size >= kMaxPoolSize || _args_pool[_size].size() > 32){
-                delete[] _args;
-            }else{
-                for(int i = 0; i < _size; i++) _args[i].reset();
-                _args_pool[_size].push_back(_args);
-            }
+        inline void _alloc(int n){
+            this->_args = _pool.alloc(n);
+            this->_size = n;
         }
 
     public:
@@ -103,7 +82,7 @@ namespace pkpy {
         const PyVar& operator[](int i) const { return _args[i]; }
 
         Args& operator=(Args&& other) noexcept {
-            _dealloc();
+            _pool.dealloc(_args, _size);
             this->_args = other._args;
             this->_size = other._size;
             other._args = nullptr;
@@ -130,14 +109,10 @@ namespace pkpy {
 
             memcpy((void*)(_args+1), (void*)old_args, sizeof(PyVar)*old_size);
             memset((void*)old_args, 0, sizeof(PyVar)*old_size);
-            if(old_size >= kMaxPoolSize || _args_pool[old_size].size() > 32){
-                delete[] old_args;
-            }else{
-                _args_pool[old_size].push_back(old_args);
-            }
+            _pool.dealloc(old_args, old_size);
         }
 
-        ~Args(){ _dealloc(); }
+        ~Args(){ _pool.dealloc(_args, _size); }
     };
 
     static const Args _zero(0);
@@ -159,4 +134,8 @@ namespace pkpy {
     }
 
     typedef Args Tuple;
-}
+
+    // declare static members
+    THREAD_LOCAL SmallArrayPool<PyVar, 10> Args::_pool;
+    // THREAD_LOCAL SmallArrayPool<NameDictNode, 1> NameDict::_pool;
+}   // namespace pkpy

Разница между файлами не показана из-за своего большого размера
+ 4 - 31
src/str.h


+ 4 - 12
src/vm.h

@@ -155,26 +155,24 @@ public:
             pkpy::NameDict& locals = *_locals;
 
             int i = 0;
-            for(const auto& name : fn.args){
+            for(StrName name : fn.args){
                 if(i < args.size()){
                     locals.emplace(name, args[i++]);
                     continue;
                 }
-                TypeError("missing positional argument '" + name + "'");
+                TypeError("missing positional argument " + name.str().escape(true));
             }
 
             locals.insert(fn.kwargs.begin(), fn.kwargs.end());
 
-            std::vector<Str> positional_overrided_keys;
             if(!fn.starred_arg.empty()){
                 pkpy::List vargs;        // handle *args
                 while(i < args.size()) vargs.push_back(args[i++]);
                 locals.emplace(fn.starred_arg, PyTuple(std::move(vargs)));
             }else{
-                for(const auto& key : fn.kwargs_order){
+                for(StrName key : fn.kwargs_order){
                     if(i < args.size()){
                         locals[key] = args[i++];
-                        positional_overrided_keys.push_back(key);
                     }else{
                         break;
                     }
@@ -188,12 +186,6 @@ public:
                     TypeError(key.escape(true) + " is an invalid keyword argument for " + fn.name + "()");
                 }
                 const PyVar& val = kwargs[i+1];
-                if(!positional_overrided_keys.empty()){
-                    auto it = std::find(positional_overrided_keys.begin(), positional_overrided_keys.end(), key);
-                    if(it != positional_overrided_keys.end()){
-                        TypeError("multiple values for argument '" + key + "'");
-                    }
-                }
                 locals[key] = val;
             }
             PyVar _module = fn._module != nullptr ? fn._module : top_frame()->_module;
@@ -634,7 +626,7 @@ public:
         setattr(_t(tp_type), __base__, _t(tp_object));
         setattr(_t(tp_object), __base__, None);
         
-        for(auto it = _types.begin(); it != _types.end(); it++){
+        for(auto it = _types.begin(); it != _types.end(); ++it){
             setattr(it->second, __name__, PyStr(it->first.str()));
         }
 

Некоторые файлы не были показаны из-за большого количества измененных файлов