Browse files

Setup Ruby side object for ThreadState

For code that heavily uses ensure blocks, creating these thread state
objects had quite a big overhead. We were abusing the Rubinius::Internal
exception for this behavior and spend a lot of time for that code in
symbol lookup for the instance variables.

This solution removes the need for any symbol lookup and this also helps
in concurrent scenarios since symbol lookup needs a lock around the
symbol table.
  • Loading branch information...
1 parent 1abe9d6 commit 3165f23f7f1a590f07d26def766575de9cc2277a @dbussink dbussink committed Feb 2, 2013
View
1 rakelib/vm.rake
@@ -110,6 +110,7 @@ field_extract_headers = %w[
vm/builtin/cache.hpp
vm/builtin/atomic.hpp
vm/builtin/character.hpp
+ vm/builtin/thread_state.hpp
]
transcoders_src_dir = File.expand_path "../../vendor/oniguruma/enc/trans", __FILE__
View
21 vm/builtin/thread_state.cpp
@@ -0,0 +1,21 @@
+#include "builtin/thread_state.hpp"
+#include "vm.hpp"
+#include "objectmemory.hpp"
+#include "builtin/class.hpp"
+
+#include "object_utils.hpp"
+
+#include "ontology.hpp"
+
+namespace rubinius {
+
+ void ThreadState::init(STATE) {
+ GO(thread_state).set(ontology::new_class(state, "ThreadState", G(object), G(rubinius)));
+ G(thread_state)->set_object_type(state, ThreadStateType);
+ }
+
+ ThreadState* ThreadState::create(STATE) {
+ return state->new_object<ThreadState>(G(thread_state));
+ }
+
+} // rubinius
View
43 vm/builtin/thread_state.hpp
@@ -0,0 +1,43 @@
+#ifndef RBX_BUILTIN_THREAD_STATE_HPP
+#define RBX_BUILTIN_THREAD_STATE_HPP
+
+#include "builtin/object.hpp"
+#include "type_info.hpp"
+
+namespace rubinius {
+
+ class ThreadState : public Object {
+ public:
+ const static object_type type = ThreadStateType;
+
+ private:
+ Exception* current_exception_; // slot
+ Object* raise_value_; // slot
+ Object* throw_dest_; // slot
+ Fixnum* raise_reason_; // slot
+ VariableScope* destination_scope_; // slot
+
+ public:
+ /* accessors */
+
+ attr_accessor(current_exception, Exception);
+ attr_accessor(raise_value, Object);
+ attr_accessor(throw_dest, Object);
+ attr_accessor(raise_reason, Fixnum);
+ attr_accessor(destination_scope, VariableScope);
+
+ /* interface */
+
+ static void init(STATE);
+
+ static ThreadState* create(STATE);
+
+ class Info : public TypeInfo {
+ public:
+ BASIC_TYPEINFO(TypeInfo)
+ };
+ };
+
+}
+
+#endif
View
3 vm/globals.hpp
@@ -52,7 +52,7 @@ namespace rubinius {
TypedRoot<Class*> string, character, symbol, io;
TypedRoot<Class*> nil_class, true_class, false_class, fixnum_class, undef_class;
TypedRoot<Class*> floatpoint, nmc, list, list_node;
- TypedRoot<Class*> channel, thread, constantscope, lookuptable;
+ TypedRoot<Class*> channel, thread, thread_state, constantscope, lookuptable;
TypedRoot<Class*> iseq, executable, native_function, iobuffer;
TypedRoot<Class*> included_module;
@@ -149,6 +149,7 @@ namespace rubinius {
list_node(&roots),
channel(&roots),
thread(&roots),
+ thread_state(&roots),
constantscope(&roots),
lookuptable(&roots),
iseq(&roots),
View
1 vm/instructions.cpp
@@ -20,6 +20,7 @@
#include "builtin/global_cache_entry.hpp"
#include "builtin/location.hpp"
#include "builtin/cache.hpp"
+#include "builtin/thread_state.hpp"
#include "instruments/tooling.hpp"
View
2 vm/instructions.def
@@ -458,7 +458,7 @@ instruction restore_exception_state() [ exception -- ]
if(top->nil_p()) {
state->vm()->thread_state()->clear();
} else {
- state->vm()->thread_state()->set_state(state, top);
+ state->vm()->thread_state()->set_state(state, as<ThreadState>(top));
}
end
View
3 vm/llvm/jit_util.cpp
@@ -25,6 +25,7 @@
#include "builtin/location.hpp"
#include "builtin/cache.hpp"
#include "builtin/encoding.hpp"
+#include "builtin/thread_state.hpp"
#include "instruments/tooling.hpp"
@@ -990,7 +991,7 @@ extern "C" {
if(top->nil_p()) {
state->vm()->thread_state()->clear();
} else {
- state->vm()->thread_state()->set_state(state, top);
+ state->vm()->thread_state()->set_state(state, as<ThreadState>(top));
}
return cNil;
View
1 vm/ontology.cpp
@@ -51,6 +51,7 @@
#include "builtin/module.hpp"
#include "builtin/class.hpp"
#include "builtin/atomic.hpp"
+#include "builtin/thread_state.hpp"
#include "environment.hpp"
#include "configuration.hpp"
View
40 vm/vm_thread_state.cpp
@@ -5,6 +5,7 @@
#include "builtin/class.hpp"
#include "builtin/symbol.hpp"
#include "builtin/exception.hpp"
+#include "builtin/thread_state.hpp"
namespace rubinius {
VMThreadState::VMThreadState(VM* state)
@@ -15,33 +16,24 @@ namespace rubinius {
, destination_scope_(state, nil<VariableScope>())
{}
- Object* VMThreadState::state_as_object(STATE) {
- if(raise_reason_ == cNone && current_exception_.get()->nil_p()) return cNil;
+ ThreadState* VMThreadState::state_as_object(STATE) {
+ if(raise_reason_ == cNone && current_exception_.get()->nil_p()) return nil<ThreadState>();
- Exception* exc = Exception::create(state);
- exc->klass(state, G(exc_vm_internal));
- exc->set_ivar(state, G(sym_reason), Fixnum::from(raise_reason_));
- exc->set_ivar(state, G(sym_destination), destination_scope());
- exc->set_ivar(state, G(sym_throw_dest), throw_dest());
-
- exc->set_ivar(state, G(sym_exception), current_exception());
- exc->set_ivar(state, G(sym_value), raise_value());
- return exc;
+ ThreadState* thread_state = ThreadState::create(state);
+ thread_state->raise_reason(state, Fixnum::from(raise_reason_));
+ thread_state->destination_scope(state, destination_scope());
+ thread_state->throw_dest(state, throw_dest());
+ thread_state->current_exception(state, current_exception());
+ thread_state->raise_value(state, raise_value());
+ return thread_state;
}
- void VMThreadState::set_state(STATE, Object* obj) {
- if(!obj->kind_of_p(state, G(exc_vm_internal))) return;
-
- Object* reason = obj->get_ivar(state, state->symbol("reason"));
- raise_reason_ = (RaiseReason)as<Fixnum>(reason)->to_native();
-
- current_exception_.set(obj->get_ivar(state, state->symbol("exception")));
- raise_value_.set(obj->get_ivar(state, state->symbol("value")));
-
- Object* vs = try_as<VariableScope>(
- obj->get_ivar(state, state->symbol("destination")));
- destination_scope_.set(vs ? vs : cNil);
- throw_dest_.set(obj->get_ivar(state, state->symbol("throw_dest")));
+ void VMThreadState::set_state(STATE, ThreadState* thread_state) {
+ raise_reason_ = (RaiseReason)thread_state->raise_reason()->to_native();
+ current_exception_.set(thread_state->current_exception());
+ raise_value_.set(thread_state->raise_value());
+ destination_scope_.set(thread_state->destination_scope());
+ throw_dest_.set(thread_state->throw_dest());
}
void VMThreadState::clear() {
View
5 vm/vm_thread_state.hpp
@@ -10,6 +10,7 @@ namespace rubinius {
class Exception;
class VariableScope;
class VM;
+ class ThreadState;
class VMThreadState {
TypedRoot<Exception*> current_exception_;
@@ -50,8 +51,8 @@ namespace rubinius {
void clear_raise();
void clear();
- Object* state_as_object(STATE);
- void set_state(STATE, Object* obj);
+ ThreadState* state_as_object(STATE);
+ void set_state(STATE, ThreadState* obj);
void raise_exception(Exception* exc);
void raise_return(Object* value, VariableScope* dest);

0 comments on commit 3165f23

Please sign in to comment.