diff --git a/.gitignore b/.gitignore index 7cf5fb19..d2b3cd85 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ plugins/flutter/example/web/lib/pocketpy.wasm plugins/flutter/src/pocketpy.h plugins/macos/pocketpy/pocketpy.h plugins/godot/godot-cpp/ +123.txt diff --git a/benchmarks/loop.py b/benchmarks/loop.py deleted file mode 100644 index f8fb4a67..00000000 --- a/benchmarks/loop.py +++ /dev/null @@ -1,6 +0,0 @@ -x = 0 - -for i in range(5000000): - x += 1 - -assert x == 5000000 \ No newline at end of file diff --git a/benchmarks/loop_0.py b/benchmarks/loop_0.py new file mode 100644 index 00000000..500999fc --- /dev/null +++ b/benchmarks/loop_0.py @@ -0,0 +1,2 @@ +for i in range(10000000): + pass diff --git a/benchmarks/loop_1.py b/benchmarks/loop_1.py new file mode 100644 index 00000000..1e43b167 --- /dev/null +++ b/benchmarks/loop_1.py @@ -0,0 +1,2 @@ +for i in range(10000000): + x = i \ No newline at end of file diff --git a/benchmarks/loop_2.py b/benchmarks/loop_2.py new file mode 100644 index 00000000..b27e5a2f --- /dev/null +++ b/benchmarks/loop_2.py @@ -0,0 +1,6 @@ +x = 0 + +for i in range(10000000): + x += 1 + +assert x == 10000000 \ No newline at end of file diff --git a/profile.sh b/profile.sh index 3b0187fc..dc05c98c 100644 --- a/profile.sh +++ b/profile.sh @@ -1,6 +1,6 @@ -g++ -o pocketpy src/main.cpp --std=c++17 -pg -O1 -fno-rtti +g++ -o pocketpy src/main.cpp --std=c++17 -pg -O2 -fno-rtti -./pocketpy benchmarks/simple.py +./pocketpy benchmarks/loop_1.py gprof pocketpy gmon.out > gprof.txt diff --git a/src/ceval.h b/src/ceval.h index 4106abea..76fcb5ec 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -55,9 +55,11 @@ PyVar VM::run_frame(Frame* frame){ else frame->push(PyRef(ref)); } continue; case OP_STORE_REF: { - PyVar obj = frame->pop_value(this); - PyVarRef r = frame->pop(); - PyRef_AS_C(r)->set(this, frame, std::move(obj)); + // PyVar obj = frame->pop_value(this); + // PyVarRef r = frame->pop(); + // PyRef_AS_C(r)->set(this, frame, std::move(obj)); + PyRef_AS_C(frame->top_1())->set(this, frame, frame->top_value(this)); + frame->_pop(); frame->_pop(); } continue; case OP_DELETE_REF: PyRef_AS_C(frame->top())->del(this, frame); @@ -228,17 +230,16 @@ PyVar VM::run_frame(Frame* frame){ } continue; case OP_GET_ITER: { PyVar obj = frame->pop_value(this); - PyVar iter_obj = asIter(obj); - PyVarRef var = frame->pop(); - check_type(var, tp_ref); - PyIter_AS_C(iter_obj)->var = var; - frame->push(std::move(iter_obj)); + PyVar iter = asIter(obj); + check_type(frame->top(), tp_ref); + PyIter_AS_C(iter)->loop_var = frame->pop(); + frame->push(std::move(iter)); } continue; case OP_FOR_ITER: { auto& it = PyIter_AS_C(frame->top()); PyVar obj = it->next(); if(obj != nullptr){ - PyRef_AS_C(it->var)->set(this, frame, std::move(obj)); + PyRef_AS_C(it->loop_var)->set(this, frame, std::move(obj)); }else{ int blockEnd = frame->co->blocks[byte.block].end; frame->jump_abs_safe(blockEnd); diff --git a/src/frame.h b/src/frame.h index 91d04923..66dc78a5 100644 --- a/src/frame.h +++ b/src/frame.h @@ -84,6 +84,11 @@ struct Frame { return _data.back(); } + inline PyVar& top_1(){ + if(_data.size() < 2) throw std::runtime_error("_data.size() < 2"); + return _data[_data.size()-2]; + } + inline PyVar top_value_offset(VM* vm, int n){ PyVar value = _data[_data.size() + n]; try_deref(vm, value); diff --git a/src/obj.h b/src/obj.h index 1f1c3ac2..596c8d41 100644 --- a/src/obj.h +++ b/src/obj.h @@ -71,7 +71,7 @@ protected: PyVar _ref; // keep a reference to the object so it will not be deleted while iterating public: virtual PyVar next() = 0; - PyVarRef var; + PyVarRef loop_var; BaseIter(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {} virtual ~BaseIter() = default; };