|
|
diff --git a/kernel/core/hash.rb b/kernel/core/hash.rb
index 0f23106..746f910 100644
--- a/kernel/core/hash.rb
+++ b/kernel/core/hash.rb
@@ -445,7 +445,7 @@ class Hash
hash = obj.hash
hash = hash % HASH_MAX unless hash.kind_of? Fixnum
- bin = hash % @bins
+ bin = hash & (@bins - 1)
entry = @values.at bin
diff --git a/kernel/core/iseq.rb b/kernel/core/iseq.rb
index 12b5076..6c82978 100644
--- a/kernel/core/iseq.rb
+++ b/kernel/core/iseq.rb
@@ -57,17 +57,17 @@ class InstructionSet
{:opcode => :push_local, :args => [:local], :stack => [0,1]},
{:opcode => :push_exception, :args => [], :stack => [0,1]},
{:opcode => :make_array, :args => [:int], :stack => [-110,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :set_ivar, :args => [:literal], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :push_ivar, :args => [:literal], :stack => [0,1]},
{:opcode => :goto_if_defined, :args => [:ip], :stack => [1,0],
:flow => :goto},
{:opcode => :push_const, :args => [:literal], :stack => [0,1]},
{:opcode => :set_const, :args => [:literal], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :set_const_at, :args => [:literal], :stack => [2,0],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :find_const, :args => [:literal], :stack => [1,1]},
{:opcode => :attach_method, :args => [:literal], :stack => [2,1],
:vm_flags => [:check_interrupts]},
@@ -82,11 +82,11 @@ class InstructionSet
{:opcode => :open_module_under, :args => [:literal], :stack => [1,1],
:vm_flags => [:check_interrupts]},
{:opcode => :unshift_tuple, :args => [], :stack => [1,2],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :cast_tuple, :args => [], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :make_rest, :args => [:int], :stack => [-110,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :dup_top, :args => [], :stack => [0,1]},
{:opcode => :pop, :args => [], :stack => [1,0]},
{:opcode => :ret, :args => [], :stack => [1,0], :flow => :return,
@@ -105,7 +105,7 @@ class InstructionSet
:vm_flags => [:terminator]},
{:opcode => :push_array, :args => [], :stack => [1,-999]},
{:opcode => :cast_array, :args => [], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :make_hash, :args => [:int], :stack => [-210,1],
:vm_flags => [:check_interrupts]},
{:opcode => :raise_exc, :args => [], :stack => [1,0], :flow => :raise,
@@ -119,15 +119,15 @@ class InstructionSet
:vm_flags => [:terminator]},
{:opcode => :passed_arg, :args => [:int], :stack => [0,1]},
{:opcode => :string_append, :args => [], :stack => [2,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :string_dup, :args => [], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :set_args, :args => [], :stack => [1,0]},
{:opcode => :get_args, :args => [], :stack => [0,1]},
{:opcode => :send_with_arg_register, :args => [:literal], :stack => [-132,1],
:flow => :send, :vm_flags => [:check_interrupts]},
{:opcode => :cast_array_for_args, :args => [:int], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :send_super_stack_with_block, :args => [:literal, :int],
:stack => [-121,1], :flow => :send, :vm_flags => [:check_interrupts]},
{:opcode => :push_my_field, :args => [:field], :stack => [0,1]},
@@ -167,9 +167,9 @@ class InstructionSet
{:opcode => :push_local_depth, :args => [:depth, :block_local],
:stack => [0,1]},
{:opcode => :set_local_depth, :args => [:depth, :block_local],
- :stack => [1,1], :vm_flags => [:check_interrupts]},
+ :stack => [1,1], :vm_flags => []},
{:opcode => :create_block, :args => [:int], :stack => [3,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :send_off_stack, :args => [], :stack => [-133,1],
:flow => :send, :vm_flags => [:check_interrupts]},
{:opcode => :locate_method, :args => [], :stack => [3,1]},
@@ -181,7 +181,7 @@ class InstructionSet
{:opcode => :from_fp, :args => [:int], :stack => [0,1]},
{:opcode => :set_local_from_fp, :args => [:local, :int], :stack => [0,0]},
{:opcode => :make_rest_fp, :args => [:int], :stack => [0,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :allocate_stack, :args => [:int], :stack => [0,-110]},
{:opcode => :deallocate_stack, :args => [:int], :stack => [-110,0]},
{:opcode => :set_local_fp, :args => [:int], :stack => [1,1]},
@@ -196,7 +196,7 @@ class InstructionSet
{:opcode => :set_literal, :args => [:literal], :stack => [0,0]},
{:opcode => :passed_blockarg, :args => [:int], :stack => [0,1]},
{:opcode => :create_block2, :args => [], :stack => [1,1],
- :vm_flags => [:check_interrupts]},
+ :vm_flags => []},
{:opcode => :cast_for_single_block_arg, :args => [], :stack => [1,1]},
{:opcode => :cast_for_multi_block_arg, :args => [], :stack => [1,1]},
{:opcode => :set_call_info, :args => [:int, :cache], :stack => [0,0]},
@@ -358,8 +358,14 @@ class InstructionSequence
sz = stream.inject(0) { |acc, ele| acc + (ele.size * InstructionSet::InstructionSize) }
@iseq = InstructionSequence.new(sz)
@offset = 0
- stream.each do |inst|
- encode inst
+ begin
+ stream.each do |inst|
+ encode inst
+ end
+ rescue Exception => e
+ STDERR.puts "Unable to encode stream:"
+ STDERR.puts stream.inspect
+ raise e
end
return @iseq
diff --git a/lib/compiler/bytecode.rb b/lib/compiler/bytecode.rb
index 093df68..bb397e2 100644
--- a/lib/compiler/bytecode.rb
+++ b/lib/compiler/bytecode.rb
@@ -1733,15 +1733,6 @@ class Node
end
# TESTED
- class MethodCall
- def use_plugin(g)
- @compiler.call_plugins.find do |plug|
- plug.handle(g, self)
- end
- end
- end
-
- # TESTED
class FCall
def allow_private?
true
@@ -1829,7 +1820,7 @@ class Node
end
def bytecode(g)
- return if use_plugin(g)
+ return if use_plugin(g, :call)
emit_args(g)
@@ -2101,6 +2092,8 @@ class Node
meth.sret
meth.close
+ use_plugin g, :method, desc
+
return desc
end
diff --git a/lib/compiler/compiler.rb b/lib/compiler/compiler.rb
index d03c2cc..9a2a92b 100644
--- a/lib/compiler/compiler.rb
+++ b/lib/compiler/compiler.rb
@@ -87,7 +87,7 @@ class Compiler
def initialize(gen_class, binding=nil)
@variables = {}
@generator_class = gen_class
- @call_plugins = []
+ @plugins = Hash.new { |h,k| h[k]= [] }
@file = "(unknown)"
@line = 0
@@ -156,7 +156,7 @@ class Compiler
end
end
- attr_reader :call_plugins
+ attr_reader :plugins
attr_accessor :generator_class
def set_position(file, line)
@@ -182,6 +182,7 @@ class Compiler
activate_default :inline
activate_default :fastsystem
activate_default :fastgeneric
+ activate_default :auto_primitive
end
def activate_default(name)
@@ -191,7 +192,7 @@ class Compiler
def activate(name)
cls = Compiler::Plugins.find_plugin(name)
raise Error, "Unknown plugin '#{name}'" unless cls
- @call_plugins << cls.new(self)
+ @plugins[cls.kind] << cls.new(self)
end
def inspect
diff --git a/lib/compiler/generator.rb b/lib/compiler/generator.rb
index 258e7f4..d7a9046 100644
--- a/lib/compiler/generator.rb
+++ b/lib/compiler/generator.rb
@@ -37,8 +37,36 @@ class Compiler
@exceptions = []
end
- attr_reader :ip, :cache_size, :exceptions
+ attr_reader :ip, :cache_size, :exceptions, :stream, :literals
attr_accessor :break, :redo, :next, :retry, :ensure_return
+
+ def ===(pattern)
+
+ return false unless @stream.size == pattern.size
+
+ i = 0
+ @stream.each do |part|
+ pat = pattern[i]
+ j = 0
+
+ if pat == :any
+ j += 1
+ next
+ end
+
+ part.each do |e|
+ s = pat[j]
+ next if s == :any
+ return false unless e == s
+
+ j += 1
+ end
+
+ i += 1
+ end
+
+ return true
+ end
def run(node)
node.bytecode self
diff --git a/lib/compiler/nodes.rb b/lib/compiler/nodes.rb
index fa82484..27d2758 100644
--- a/lib/compiler/nodes.rb
+++ b/lib/compiler/nodes.rb
@@ -87,6 +87,12 @@ class Node
obj.nil? ? Nil.new(@compiler) : obj
end
+ def use_plugin(g, kind, *args)
+ @compiler.plugins[kind].find do |plug|
+ plug.handle(g, self, *args)
+ end
+ end
+
# Start of Node subclasses
class ClosedScope < Node
diff --git a/lib/compiler/plugins.rb b/lib/compiler/plugins.rb
index 0c1cb6a..e0d3869 100644
--- a/lib/compiler/plugins.rb
+++ b/lib/compiler/plugins.rb
@@ -17,10 +17,15 @@ module Compiler::Plugins
@compiler = compiler
end
- def self.plugin(name)
+ def self.plugin(name, kind=:call)
+ @kind = kind
Compiler::Plugins.add_plugin name, self
end
+ def self.kind
+ @kind
+ end
+
def call_match(c, const, method)
return false unless c.call?
return false unless c.method == method
@@ -314,4 +319,60 @@ module Compiler::Plugins
end
end
+
+ class AutoPrimitiveDetection < Plugin
+ plugin :auto_primitive, :method
+
+ SingleInt = [[:check_argcount, 0, 0], [:push_int, :any], [:sret]]
+ Literal = [[:check_argcount, 0, 0], [:push_literal, 0], [:sret]]
+ Self = [[:check_argcount, 0, 0], [:push_self], [:sret]]
+ Ivar = [[:check_argcount, 0, 0], [:push_ivar, 0], [:sret]]
+ Field = [[:check_argcount, 0, 0], [:push_my_field, :any], [:sret]]
+
+ def handle(g, obj, meth)
+ ss = meth.generator.stream
+
+ return true unless ss.size == 3
+
+ gen = meth.generator
+
+ if gen === SingleInt
+ meth.generator.literals[0] = ss[1][1]
+ meth.generator.as_primitive :opt_push_literal
+ elsif gen === Literal
+ # The value we want is already in literal 0
+ meth.generator.as_primitive :opt_push_literal
+ elsif gen === Self
+ meth.generator.as_primitive :opt_push_self
+ elsif gen === Ivar
+ meth.generator.as_primitive :opt_push_ivar
+ elsif gen === Field
+ meth.generator.literals[0] = ss[1][1]
+ meth.generator.as_primitive :opt_push_my_field
+ else
+ case ss[1].first
+ when :push_nil
+ lit = nil
+ when :push_true
+ lit = true
+ when :push_false
+ lit = false
+ when :meta_push_0
+ lit = 0
+ when :meta_push_1
+ lit = 1
+ when :meta_push_2
+ lit = 2
+ else
+ return true
+ end
+
+ meth.generator.literals[0] = lit
+ meth.generator.as_primitive :opt_push_literal
+ end
+
+ true
+ end
+
+ end
end
diff --git a/lib/timeout.rb b/lib/timeout.rb
index dc92964..ac12c6e 100644
--- a/lib/timeout.rb
+++ b/lib/timeout.rb
@@ -5,6 +5,7 @@
#
# = Copyright
#
+# Copyright - (C) 2008 Evan Phoenix
# Copyright:: (C) 2000 Network Applied Communication Laboratory, Inc.
# Copyright:: (C) 2000 Information-technology Promotion Agency, Japan
#
@@ -27,6 +28,8 @@
# }
#
+require 'thread'
+
module Timeout
##
@@ -35,6 +38,89 @@ module Timeout
class Error b.left }
+ end
+
+ slept_for = sleep(min.left)
+
+ @mutex.synchronize do
+ @requests.delete_if do |r|
+ if r.elapsed(slept_for)
+ r.cancel
+ true
+ else
+ false
+ end
+ end
+ end
+
+ end
+ end
+
+ req = TimeoutRequest.new(time, Thread.current, exc)
+
+ @mutex.synchronize do
+ @requests << req
+ end
+
+ @controller.run
+
+ return req
+ end
+
##
# Executes the method's block. If the block execution terminates before +sec+
# seconds has passed, it returns true. If not, it terminates the execution
@@ -43,20 +129,17 @@ module Timeout
# Note that this is both a method of module Timeout, so you can 'include
# Timeout' into your classes so they have a #timeout method, as well as a
# module method, so you can call it directly as Timeout.timeout().
-
+
def timeout(sec, exception=Error)
return yield if sec == nil or sec.zero?
raise ThreadError, "timeout within critical session" if Thread.critical
+
+ req = Timeout.add_timeout sec, exception
+
begin
- x = Thread.current
- y = Thread.start {
- sleep sec
- x.raise exception, "execution expired" if x.alive?
- }
yield sec
- # return true
ensure
- y.kill if y and y.alive?
+ req.abort
end
end
diff --git a/shotgun/Makefile b/shotgun/Makefile
index 3427377..bf54b7c 100644
--- a/shotgun/Makefile
+++ b/shotgun/Makefile
@@ -127,7 +127,7 @@ dtrace.h: rubinius.d
/usr/sbin/dtrace -h -s rubinius.d -o dtrace.h
rubinius.bin: $(RBLIB) main.o
- $(COMP) -o rubinius.bin main.o $(RBLIB) $(BIN_RPATH)
+ $(COMP) -o rubinius.bin main.o $(RBLIB) $(BIN_RPATH) $(LDFLAGS)
test/test_state: test/test_state.c library
$(COMP) -c -o test/test_state.o test/test_state.c $(CFLAGS)
diff --git a/shotgun/lib/Makefile b/shotgun/lib/Makefile
index 2bdff86..353aeec 100644
--- a/shotgun/lib/Makefile
+++ b/shotgun/lib/Makefile
@@ -54,7 +54,9 @@ ifeq ($(UNAME),SunOS)
LIBS+= -lsocket
endif
-ifdef DEV
+ifdef PROF
+ OPTIMIZATIONS=-O2
+else ifdef DEV
OPTIMIZATIONS=
else
INLINE_OPTS=-Winline -finline-limit=2000 --param max-inline-insns-single=3500 --param large-function-growth=7000 --param inline-unit-growth=1500
diff --git a/shotgun/lib/cpu.c b/shotgun/lib/cpu.c
index 1c7dc07..b892d45 100644
--- a/shotgun/lib/cpu.c
+++ b/shotgun/lib/cpu.c
@@ -131,7 +131,6 @@ void cpu_add_roots(STATE, cpu c, ptr_array roots) {
ar(c->sender);
ar(c->self);
- ar(c->cache);
ar(c->exception);
ar(c->enclosing_class);
ar(c->main);
@@ -142,6 +141,7 @@ void cpu_add_roots(STATE, cpu c, ptr_array roots) {
ar(c->debug_channel);
ar(c->control_channel);
ar(c->current_scope);
+ ar(c->locals);
len = ptr_array_length(c->paths);
ptr_array_append(roots, (xpointer)I2N(len));
// printf("Paths: %d\n", len);
@@ -190,7 +190,6 @@ void cpu_update_roots(STATE, cpu c, ptr_array roots, int start) {
ar(c->sender);
ar(c->self);
- ar(c->cache);
ar(c->exception);
ar(c->enclosing_class);
ar(c->main);
@@ -201,6 +200,7 @@ void cpu_update_roots(STATE, cpu c, ptr_array roots, int start) {
ar(c->debug_channel);
ar(c->control_channel);
ar(c->current_scope);
+ ar(c->locals);
tmp = ptr_array_get_index(roots, start++);
len = N2I((OBJECT)tmp);
for(i = 0; i < len; start++, i++) {
@@ -247,6 +247,9 @@ OBJECT cpu_new_exception2(STATE, cpu c, OBJECT klass, const char *msg, ...) {
OBJECT cpu_const_get_in_context(STATE, cpu c, OBJECT sym) {
OBJECT cur, klass, start, hsh, val;
OBJECT cref, cbase;
+ int sym_hash;
+
+ sym_hash = object_hash_int(state, sym);
/* Look up the lexical scope first */
@@ -263,7 +266,7 @@ OBJECT cpu_const_get_in_context(STATE, cpu c, OBJECT sym) {
if(klass == state->global->object) break;
hsh = module_get_constants(klass);
- val = hash_find_undef(state, hsh, sym);
+ val = hash_get_undef(state, hsh, sym_hash);
if(val != Qundef) return val;
cbase = staticscope_get_parent(cbase);
@@ -274,7 +277,7 @@ OBJECT cpu_const_get_in_context(STATE, cpu c, OBJECT sym) {
while(!NIL_P(cur) && cur != state->global->object) {
hsh = module_get_constants(cur);
- val = hash_find_undef(state, hsh, sym);
+ val = hash_get_undef(state, hsh, sym_hash);
if(val != Qundef) return val;
cur = module_get_superclass(cur);
}
@@ -282,7 +285,7 @@ OBJECT cpu_const_get_in_context(STATE, cpu c, OBJECT sym) {
// As a last rescue, we search in Object's constants
hsh = module_get_constants(state->global->object);
- val = hash_find_undef(state, hsh, sym);
+ val = hash_get_undef(state, hsh, sym_hash);
if(val != Qundef) return val;
stack_push(sym);
diff --git a/shotgun/lib/cpu.h b/shotgun/lib/cpu.h
index 2664219..db6ea6e 100644
--- a/shotgun/lib/cpu.h
+++ b/shotgun/lib/cpu.h
@@ -92,7 +92,7 @@ struct cpu_task {
struct rubinius_cpu {
/* Normal registers are saved and restored per new method call . */
OBJECT self, sender;
- OBJECT cache;
+ OBJECT locals;
IP_TYPE *data;
unsigned short type;
unsigned short argcount;
@@ -281,12 +281,16 @@ OBJECT cpu_sampler_disable(STATE);
#define cpu_stack_top(state, c) (*(c)->sp_ptr)
#define cpu_stack_set_top(state, c, oop) (*(c)->sp_ptr = oop)
-typedef int (*prim_func)(STATE, cpu c, struct message *msg);
-void cpu_patch_primitive(STATE, struct message *msg, prim_func func);
-int cpu_perform_system_primitive(STATE, cpu c, int prim, struct message *msg);
+#include "shotgun/lib/sendsite.h"
-void cpu_patch_ffi(STATE, struct message *msg);
+void cpu_initialize_sendsite(STATE, struct send_site *ss);
+typedef int (*prim_func)(STATE, cpu c, const struct message *msg);
+void cpu_patch_primitive(STATE, const struct message *msg, prim_func func);
+int cpu_perform_system_primitive(STATE, cpu c, int prim, const struct message *msg);
+
+void cpu_patch_ffi(STATE, const struct message *msg);
void ffi_call(STATE, cpu c, OBJECT ptr);
+void ffi_autorelease(OBJECT ptr, int ar);
OBJECT ffi_new_pointer(STATE, void *ptr);
#endif /* RBS_CPU_H */
diff --git a/shotgun/lib/cpu_instructions.c b/shotgun/lib/cpu_instructions.c
index 3ea7cbd..17f771e 100644
--- a/shotgun/lib/cpu_instructions.c
+++ b/shotgun/lib/cpu_instructions.c
@@ -523,7 +523,7 @@ static inline OBJECT _allocate_context(STATE, cpu c, OBJECT meth, int locals) {
return ctx;
}
-static inline OBJECT cpu_create_context(STATE, cpu c, struct message *msg) {
+static inline OBJECT cpu_create_context(STATE, cpu c, const struct message *msg) {
OBJECT ctx;
struct fast_context *fc;
@@ -568,12 +568,6 @@ OBJECT cpu_create_block_context(STATE, cpu c, OBJECT env, int sp) {
fc->method_module = Qnil;
fc->type = FASTCTX_BLOCK;
- /* If post send is nil, that means we're not allowed to return directly to
- the home context. */
- if(NIL_P(blokenv_get_post_send(env))) {
- fc->flags |= CTX_FLAG_NO_LONG_RETURN;
- }
-
return ctx;
}
@@ -612,7 +606,7 @@ void cpu_raise_primitive_failure(STATE, cpu c, int primitive_idx) {
cpu_raise_exception(state, c, primitive_failure);
}
-static inline int cpu_try_primitive(STATE, cpu c, struct message *msg) {
+static inline int cpu_try_primitive(STATE, cpu c, const struct message *msg) {
int prim, req;
OBJECT prim_obj;
@@ -736,12 +730,8 @@ inline void cpu_restore_context_with_home(STATE, cpu c, OBJECT ctx, OBJECT home)
c->data = fc->data;
c->type = fc->type;
-
- if(fc->type != FASTCTX_NMC) {
- c->cache = fast_fetch(fc->method, CMETHOD_f_CACHE);
- } else {
- c->cache = Qnil;
- }
+
+ c->locals = FASTCTX(home)->locals;
c->sender = fc->sender;
c->sp = fc->sp;
@@ -919,20 +909,6 @@ inline int cpu_return_to_sender(STATE, cpu c, OBJECT val, int consider_block, in
printf("CTX: remote return from %p to %p\n", c->active_context, destination);
}
- /* If the current context is marked as not being allowed to
- return long, raise an exception instead. */
- if(FASTCTX(c->active_context)->flags & CTX_FLAG_NO_LONG_RETURN) {
- OBJECT exc;
- home = rbs_const_get(state, BASIC_CLASS(object), "IllegalLongReturn");
-
- exc = cpu_new_exception(state, c, home, "Unable to perform a long return");
- object_set_ivar(state, exc, SYM("@return_value"), val);
-
- cpu_raise_exception(state, c, exc);
-
- return TRUE;
- }
-
/* If we're making a non-local return to a stack context... */
if(om_on_stack(state->om, destination)) {
/* If we're returning to a reference'd context, reset the
@@ -1079,14 +1055,70 @@ static inline void cpu_activate_method(STATE, cpu c, struct message *msg) {
cpu_restore_context_with_home(state, c, ctx, ctx);
}
+static inline void cpu_perform(STATE, cpu c, const struct message *msg) {
+ OBJECT ctx;
+
+ c->depth++;
+ if(c->depth == CPU_MAX_DEPTH) {
+ machine_handle_fire(FIRE_STACK);
+ }
+
+ ctx = cpu_create_context(state, c, msg);
+
+ /* If it was missing, setup some extra data in the MethodContext for
+ the method_missing method to check out, to see why it was missing. */
+ if(msg->missing && msg->priv) {
+ methctx_reference(state, ctx);
+ object_set_ivar(state, ctx, SYM("@send_private"), Qtrue);
+ }
+
+ cpu_save_registers(state, c, msg->args);
+ cpu_restore_context_with_home(state, c, ctx, ctx);
+}
+
+
+static inline void
+cpu_patch_mono(STATE, struct send_site *ss, struct message *msg);
+
+static inline void
+cpu_patch_missing(STATE, struct send_site *ss, struct message *msg);
+
+static void
+_cpu_ss_basic(STATE, cpu c, struct send_site *ss, struct message *msg) {
+ msg->missing = 0;
+
+ sassert(cpu_locate_method(state, c, msg));
+
+ /* If it's not method_missing, cache the details of msg in the send_site */
+ if(!msg->missing) {
+ cpu_patch_mono(state, ss, msg);
+ } else {
+ cpu_patch_missing(state, ss, msg);
+ msg->args += 1;
+ stack_push(msg->name);
+ }
+
+ if(cpu_try_primitive(state, c, msg)) return;
+
+ cpu_perform(state, c, msg);
+}
+
+void cpu_initialize_sendsite(STATE, struct send_site *ss) {
+ ss->lookup = _cpu_ss_basic;
+}
+
/* Send Site specialization 1: execute a primitive directly. */
-static int _cpu_ss_mono_prim(STATE, cpu c, struct send_site *ss, struct message *msg) {
+static void _cpu_ss_mono_prim(STATE, cpu c, struct send_site *ss,
+ struct message *msg) {
prim_func func;
int _orig_sp;
OBJECT *_orig_sp_ptr;
- if(_real_class(state, msg->recv) != ss->data1) return SEND_SITE_ABORT;
+ if(_real_class(state, msg->recv) != ss->data1) {
+ _cpu_ss_basic(state, c, ss, msg);
+ return;
+ }
_orig_sp_ptr = c->sp_ptr;
_orig_sp = c->sp;
@@ -1100,15 +1132,13 @@ static int _cpu_ss_mono_prim(STATE, cpu c, struct send_site *ss, struct message
c->sp_ptr = _orig_sp_ptr;
c->sp = _orig_sp;
- return SEND_SITE_BYTECODE;
+ cpu_perform(state, c, msg);
}
-
- return SEND_SITE_DONE;
}
/* Called before a primitive is run the slow way, allowing the send_site to be patch
* to call the primitive directly. */
-void cpu_patch_primitive(STATE, struct message *msg, prim_func func) {
+void cpu_patch_primitive(STATE, const struct message *msg, prim_func func) {
struct send_site *ss;
if(!REFERENCE_P(msg->send_site)) return;
@@ -1124,27 +1154,29 @@ void cpu_patch_primitive(STATE, struct message *msg, prim_func func) {
}
/* Send Site specialization 2: Run an ffi function directly. */
-static int _cpu_ss_mono_ffi(STATE, cpu c, struct send_site *ss, struct message *msg) {
+static void _cpu_ss_mono_ffi(STATE, cpu c, struct send_site *ss,
+ struct message *msg) {
rni_context *ctx;
nf_stub_ffi func;
func = (nf_stub_ffi)ss->c_data;
// printf("mono-ffi: %p (%s)\n", func, _inspect(ss->name));
- if(_real_class(state, msg->recv) != ss->data1) return SEND_SITE_ABORT;
+ if(_real_class(state, msg->recv) != ss->data1) {
+ _cpu_ss_basic(state, c, ss, msg);
+ return;
+ }
ctx = subtend_retrieve_context();
ctx->state = state;
ctx->cpu = c;
func();
-
- return SEND_SITE_DONE;
}
/* Called before an FFI function is run the slow way, allowing the send_site to be patch
* to call the function directly. */
-void cpu_patch_ffi(STATE, struct message *msg) {
+void cpu_patch_ffi(STATE, const struct message *msg) {
struct send_site *ss;
if(!REFERENCE_P(msg->send_site)) return;
@@ -1171,25 +1203,61 @@ void cpu_patch_ffi(STATE, struct message *msg) {
}
/* Send Site specialzitation 3: simple monomorphic last implemenation cache. */
-static int _cpu_ss_mono(STATE, cpu c, struct send_site *ss, struct message *msg) {
- if(_real_class(state, msg->recv) != ss->data1) return SEND_SITE_ABORT;
+static void _cpu_ss_mono(STATE, cpu c, struct send_site *ss,
+ struct message *msg) {
+
+ if(_real_class(state, msg->recv) != ss->data1) {
+ _cpu_ss_basic(state, c, ss, msg);
+ return;
+ }
+
msg->method = ss->data2;
msg->module = ss->data3;
+
+ if(cpu_try_primitive(state, c, msg)) return;
- return SEND_SITE_RESOLVED;
+ cpu_perform(state, c, msg);
}
/* Saves the details of +msg+ in +ss+ and install _cpu_ss_mono in +ss+, so
* that the next time +ss+ is used, it will try the cache details. */
static inline void
-cpu_initialize_sendsite(STATE, struct send_site *ss, struct message *msg) {
+cpu_patch_mono(STATE, struct send_site *ss, struct message *msg) {
ss->lookup = _cpu_ss_mono;
SET_STRUCT_FIELD(msg->send_site, ss->data1, _real_class(state, msg->recv));
SET_STRUCT_FIELD(msg->send_site, ss->data2, msg->method);
SET_STRUCT_FIELD(msg->send_site, ss->data3, msg->module);
}
-static void _cpu_on_no_method(STATE, cpu c, struct message *msg) {
+static void
+_cpu_ss_missing(STATE, cpu c, struct send_site *ss, struct message *msg) {
+ if(_real_class(state, msg->recv) != ss->data1) {
+ _cpu_ss_basic(state, c, ss, msg);
+ return;
+ }
+
+ msg->method = ss->data2;
+ msg->module = ss->data3;
+
+ msg->args += 1;
+ stack_push(msg->name);
+
+ if(cpu_try_primitive(state, c, msg)) return;
+
+ cpu_perform(state, c, msg);
+}
+
+/* Saves the details of +msg+ in +ss+ and install _cpu_ss_mono in +ss+, so
+ * that the next time +ss+ is used, it will try the cache details. */
+static inline void
+cpu_patch_missing(STATE, struct send_site *ss, struct message *msg) {
+ ss->lookup = _cpu_ss_missing;
+ SET_STRUCT_FIELD(msg->send_site, ss->data1, _real_class(state, msg->recv));
+ SET_STRUCT_FIELD(msg->send_site, ss->data2, msg->method);
+ SET_STRUCT_FIELD(msg->send_site, ss->data3, msg->module);
+}
+
+static void _cpu_on_no_method(STATE, cpu c, const struct message *msg) {
char *str;
OBJECT exc;
@@ -1205,60 +1273,56 @@ static void _cpu_on_no_method(STATE, cpu c, struct message *msg) {
/* Layer 4: send. Primary method calling function. */
inline void cpu_send_message(STATE, cpu c, struct message *msg) {
- OBJECT ctx;
struct send_site *ss;
#ifdef TIME_LOOKUP
uint64_t start = measure_cpu_time();
#endif
-#if ENABLE_DTRACE
- if(RUBINIUS_VM_SEND_BEGIN_ENABLED()) {
- RUBINIUS_VM_SEND_BEGIN();
- }
-#endif
+ //if(SENDSITE_P(msg->send_site)) {
+ ss = SENDSITE(msg->send_site);
+ msg->name = ss->name;
+ ss->lookup(state, c, ss, msg);
+ /*
+ } else {
+ msg->name = msg->send_site;
+ msg->send_site = Qnil;
- msg->missing = 0;
+ msg->missing = 0;
- ss = SENDSITE(msg->send_site);
- msg->name = ss->name;
-
- /* If the send_site has a custom lookup function, use it. */
- if(ss->lookup) {
- switch(ss->lookup(state, c, ss, msg)) {
- case SEND_SITE_DONE: /* lookup did all the work, we're done. */
- return;
- case SEND_SITE_RESOLVED: /* lookup filled in msg with the details. */
- goto dispatch;
- case SEND_SITE_BYTECODE: /* same as resolved, but only run the bytecode */
- goto bytecode;
+ sassert(cpu_locate_method(state, c, msg));
+
+ if(msg->missing) {
+ msg->args += 1;
+ stack_push(msg->name);
}
+
+ if(cpu_try_primitive(state, c, msg)) return;
+
+ cpu_perform(state, c, msg);
}
+ */
- /* We're here if SEND_SITE_ABORT was returned, or if there was no
- * ->lookup. locate method fills in msg with the details. */
+#ifdef TIME_LOOKUP
+ state->lookup_time += (measure_cpu_time() - start);
+#endif
+}
+
+void cpu_send_message_external(STATE, cpu c, struct message *msg) {
+ OBJECT ctx;
+
if(!cpu_locate_method(state, c, msg)) {
- /* Only happens if locate_method can't even find method_missing. */
_cpu_on_no_method(state, c, msg);
- goto done;
+ return;
}
-
- /* If it's not method_missing, cache the details of msg in the send_site */
- if(!msg->missing) cpu_initialize_sendsite(state, ss, msg);
-
-dispatch:
-
- /* If using method_missing, put the name of the method on the stack and
- * add an argument. */
+
if(msg->missing) {
msg->args += 1;
stack_push(msg->name);
} else {
- /* Otherwise try and run this method as a primitive. */
- if(cpu_try_primitive(state, c, msg)) goto done;
+ if(cpu_try_primitive(state, c, msg)) return;
}
-
-bytecode:
+
c->depth++;
if(c->depth == CPU_MAX_DEPTH) {
machine_handle_fire(FIRE_STACK);
@@ -1275,19 +1339,12 @@ bytecode:
cpu_save_registers(state, c, msg->args);
cpu_restore_context_with_home(state, c, ctx, ctx);
-
-done:
-#ifdef TIME_LOOKUP
- state->lookup_time += (measure_cpu_time() - start);
-#endif
-
- return;
}
+
/* A version used when there is no send_site. */
void cpu_send(STATE, cpu c, OBJECT recv, OBJECT sym, int args, OBJECT block) {
struct message msg;
- OBJECT ctx;
msg.recv = recv;
msg.name = sym;
@@ -1299,35 +1356,8 @@ void cpu_send(STATE, cpu c, OBJECT recv, OBJECT sym, int args, OBJECT block) {
msg.send_site = Qnil;
c->call_flags = 0;
-
- if(!cpu_locate_method(state, c, &msg)) {
- _cpu_on_no_method(state, c, &msg);
- return;
- }
-
- if(msg.missing) {
- msg.args += 1;
- stack_push(msg.name);
- } else {
- if(cpu_try_primitive(state, c, &msg)) return;
- }
-
- c->depth++;
- if(c->depth == CPU_MAX_DEPTH) {
- machine_handle_fire(FIRE_STACK);
- }
-
- ctx = cpu_create_context(state, c, &msg);
- /* If it was missing, setup some extra data in the MethodContext for
- the method_missing method to check out, to see why it was missing. */
- if(msg.missing && msg.priv) {
- methctx_reference(state, ctx);
- object_set_ivar(state, ctx, SYM("@send_private"), Qtrue);
- }
-
- cpu_save_registers(state, c, msg.args);
- cpu_restore_context_with_home(state, c, ctx, ctx);
+ cpu_send_message_external(state, c, &msg);
}
void cpu_raise_exception(STATE, cpu c, OBJECT exc) {
diff --git a/shotgun/lib/cpu_primitives.c b/shotgun/lib/cpu_primitives.c
index cf99336..356ca11 100644
--- a/shotgun/lib/cpu_primitives.c
+++ b/shotgun/lib/cpu_primitives.c
@@ -118,7 +118,7 @@ void ffi_call(STATE, cpu c, OBJECT ptr);
#include "shotgun/lib/primitive_implementation.gen"
-int cpu_perform_system_primitive(STATE, cpu c, int prim, struct message *msg) {
+int cpu_perform_system_primitive(STATE, cpu c, int prim, const struct message *msg) {
int _ret = TRUE;
int _orig_sp;
OBJECT *_orig_sp_ptr;
diff --git a/shotgun/lib/ffi_util.c b/shotgun/lib/ffi_util.c
index 53ef154..5c4e033 100644
--- a/shotgun/lib/ffi_util.c
+++ b/shotgun/lib/ffi_util.c
@@ -259,6 +259,22 @@ void *ffi_add_ptr(char *ptr, int offset) {
return (void*)(ptr + offset);
}
+long ffi_major(dev_t n) {
+#ifdef major
+ return major(n);
+#else
+ return -1;
+#endif
+}
+
+long ffi_minor(dev_t n) {
+#ifdef minor
+ return minor(n);
+#else
+ return -1;
+#endif
+}
+
/* FIXME: Kill these after the next rebuild of the stable RBAs */
int ffi_seek_set() { return SEEK_SET; }
int ffi_seek_cur() { return SEEK_CUR; }
diff --git a/shotgun/lib/hash.c b/shotgun/lib/hash.c
index 96b29f8..5cf3f71 100644
--- a/shotgun/lib/hash.c
+++ b/shotgun/lib/hash.c
@@ -2,90 +2,22 @@
#include "shotgun/lib/tuple.h"
#include "shotgun/lib/hash.h"
-/* Adapted from st.c in 1.8.5 */
-
-/*
-Table of prime numbers 2^n+a, 2<=n<=30.
-*/
-static const long primes[] = {
- 8 + 3,
- 16 + 3,
- 23,
- 32 + 5,
- 43,
- 53,
- 59,
- 64 + 3,
- 73,
- 83,
- 97,
- 109,
- 128 + 3,
- 137,
- 149,
- 157,
- 167,
- 179,
- 191,
- 197,
- 211,
- 229,
- 256 + 27,
- 512 + 9,
- 1024 + 9,
- 2048 + 5,
- 4096 + 3,
- 8192 + 27,
- 16384 + 43,
- 32768 + 3,
- 65536 + 45,
- 131072 + 29,
- 262144 + 3,
- 524288 + 21,
- 1048576 + 7,
- 2097152 + 17,
- 4194304 + 15,
- 8388608 + 9,
- 16777216 + 43,
- 33554432 + 35,
- 67108864 + 15,
- 134217728 + 29,
- 268435456 + 3,
- 536870912 + 11,
- 1073741824 + 85,
- 0
-};
-
#define MINSIZE 8
-static int hash_new_size(int size) {
- int i, p;
- int newsize;
-
- for (i = 0, newsize = MINSIZE;
- i < sizeof(primes)/sizeof(primes[0]);
- i++)
- {
- p = primes[i];
- if(p > size) return p;
- }
- /* Ran out of polynomials */
- return -1; /* should raise exception */
-}
-
-#define MAX_DENSITY 5
-
-/* end adaptation. */
+#define MAX_DENSITY 0.75
#define Increments 16
+#define find_bin(hash, total) (hash & (total - 1))
+
OBJECT hash_new(STATE) {
OBJECT hsh;
hsh = hash_allocate(state);
- hash_setup(state, hsh, 0);
+ hash_setup(state, hsh, MINSIZE);
return hsh;
}
+/* size MUST be a power of 2 */
OBJECT hash_new_sized(STATE, int size) {
OBJECT hsh;
hsh = hash_allocate(state);
@@ -95,7 +27,7 @@ OBJECT hash_new_sized(STATE, int size) {
void hash_setup(STATE, OBJECT hsh, int size) {
int sz;
- sz = hash_new_size(size);
+ sz = size == 0 ? MINSIZE : size;
hash_set_keys(hsh, tuple_new(state, sz));
hash_set_values(hsh, tuple_new(state, sz));
hash_set_bins(hsh, I2N(sz));
@@ -147,7 +79,7 @@ static void hash_rehash(STATE, OBJECT hsh, int _ents) {
OBJECT tbl, tup, ent, next;
old_bins = N2I(hash_get_bins(hsh));
- new_bins = hash_new_size(old_bins + 1);
+ new_bins = old_bins * 2;
tup = tuple_new(state, new_bins);
tbl = hash_get_values(hsh);
@@ -159,7 +91,7 @@ static void hash_rehash(STATE, OBJECT hsh, int _ents) {
next = tuple_at(state, ent, 3);
hv = (unsigned int)N2I(tuple_at(state, ent, 0));
- bin = hv % new_bins;
+ bin = find_bin(hv, new_bins);
tuple_put(state, ent, 3, tuple_at(state, tup, (int)bin));
tuple_put(state, tup, (int)bin, ent);
@@ -218,7 +150,7 @@ OBJECT hash_find_entry(STATE, OBJECT h, unsigned int hsh) {
OBJECT entry, th;
bins = (unsigned int)N2I(hash_get_bins(h));
- bin = hsh % bins;
+ bin = find_bin(hsh, bins);
entry = tuple_at(state, hash_get_values(h), bin);
// printf("start: %x, %ud, %d, %d\n", entry, hsh, bin, N2I(hash_get_bins(h)));
@@ -249,7 +181,7 @@ OBJECT hash_add(STATE, OBJECT h, unsigned int hsh, OBJECT key, OBJECT data) {
i = N2I(hash_get_entries(h));
b = N2I(hash_get_bins(h));
- if(i / b > MAX_DENSITY) {
+ if((double)i / (double)b > MAX_DENSITY) {
hash_rehash(state, h, i);
}
@@ -298,8 +230,8 @@ OBJECT hash_get_undef(STATE, OBJECT hash, unsigned int hsh) {
OBJECT hash_delete(STATE, OBJECT self, unsigned int hsh) {
unsigned int bin;
OBJECT entry, th, lk, val, lst;
-
- bin = hsh % N2I(hash_get_bins(self));
+
+ bin = find_bin(hsh, N2I(hash_get_bins(self)));
entry = tuple_at(state, hash_get_values(self), bin);
lst = Qnil;
diff --git a/shotgun/lib/instructions.rb b/shotgun/lib/instructions.rb
index 9d3e740..a57dd73 100644
--- a/shotgun/lib/instructions.rb
+++ b/shotgun/lib/instructions.rb
@@ -237,7 +237,12 @@ CODE
end
def push_local
- "next_int; stack_push(fast_fetch(cpu_current_locals(state, c), _int));"
+ <<-CODE
+ next_int;
+ stack_push(fast_fetch(c->locals, _int));
+ CODE
+
+ # "next_int; stack_push(fast_fetch(cpu_current_locals(state, c), _int));"
end
def push_local_depth
@@ -415,7 +420,7 @@ CODE
next_int;
t1 = stack_pop();
// printf("Set local %d to %s\\n", _int, _inspect(t1));
- t2 = cpu_current_locals(state, c);
+ t2 = c->locals;
if(t2->gc_zone == 0) {
sassert(_int < NUM_FIELDS(t2) && "locals tuple sized wrong");
fast_unsafe_set(t2, _int, t1);
diff --git a/shotgun/lib/primitive_names.rb b/shotgun/lib/primitive_names.rb
index 00921c8..e71477b 100755
--- a/shotgun/lib/primitive_names.rb
+++ b/shotgun/lib/primitive_names.rb
@@ -194,7 +194,11 @@ module Bytecode
:get_ivar,
:set_index,
:get_index,
- :dispatch_as_method
+ :dispatch_as_method,
+ :opt_push_literal,
+ :opt_push_self,
+ :opt_push_my_field,
+ :opt_push_ivar
]
end
end
diff --git a/shotgun/lib/primitives.rb b/shotgun/lib/primitives.rb
index 99e021b..2a63ed8 100644
--- a/shotgun/lib/primitives.rb
+++ b/shotgun/lib/primitives.rb
@@ -2,13 +2,21 @@ require File.dirname(__FILE__) + '/primitive_names'
class ShotgunPrimitives
+ OldMap = {
+ :set_ivar => 1024,
+ :get_ivar => 1025,
+ :set_index => 1026,
+ :get_index => 1027,
+ :dispatch_as_method => 1028
+ }
+
def generate_select(fd, op="prim")
i = 1
order = Bytecode::Compiler::Primitives
File.open("primitive_implementation.gen", "w") do |f|
order.each do |ins|
- f.puts "int cpu_primitive_#{ins}(STATE, cpu c, struct message *msg) {"
+ f.puts "int cpu_primitive_#{ins}(STATE, cpu c, const struct message *msg) {"
f.puts send(ins)
f.puts " DONE();\n}"
end
@@ -30,6 +38,9 @@ class ShotgunPrimitives
fd.puts " // NOOP is 0 and signifies a method with no primitive"
order.each do |ins|
fd.puts "case #{i}: { // #{ins}"
+ if old = OldMap[ins]
+ fd.puts "case #{old}:"
+ end
fd.puts " cpu_patch_primitive(state, msg, cpu_primitive_#{ins});"
fd.puts " _ret = cpu_primitive_#{ins}(state, c, msg);"
fd.puts " break;\n}"
@@ -71,6 +82,8 @@ class ShotgunPrimitives
for(i = 0; pi[i].name; i++) {
if(!strcmp(target, pi[i].name)) return pi[i].index;
}
+
+ printf("Unknown primitive %s\\n", target);
return -1;
}
@@ -616,6 +629,7 @@ class ShotgunPrimitives
def gettimeofday
<<-CODE
+ OBJECT t1;
struct timeval tv;
/* don't fill in the 2nd argument here. getting the timezone here
@@ -624,11 +638,11 @@ class ShotgunPrimitives
gettimeofday(&tv, NULL);
/* update Time::TIMEVAL_FIELDS when changing order of fields */
- msg->recv = array_new(state, 2);
- array_set(state, msg->recv, 0, ML2N(tv.tv_sec));
- array_set(state, msg->recv, 1, ML2N(tv.tv_usec));
+ t1 = array_new(state, 2);
+ array_set(state, t1, 0, ML2N(tv.tv_sec));
+ array_set(state, t1, 1, ML2N(tv.tv_usec));
- RET(msg->recv);
+ RET(t1);
CODE
end
@@ -1101,7 +1115,7 @@ class ShotgunPrimitives
k = bytearray_bytes(state, msg->recv);
GUARD( j >= 0 && j < k );
-
+
indexed = (unsigned char*)bytearray_byte_address(state, msg->recv);
indexed += j;
t2 = UI2N(*indexed = N2I(t2));
@@ -1482,18 +1496,18 @@ class ShotgunPrimitives
}
err = tcgetattr(STDOUT_FILENO, &ts);
-
+
if(err == -1) { /* TODO: handle errno */
RET(Qfalse);
}
-
+
ts.c_lflag &= ~ICANON; /* -icanon */
ts.c_lflag &= ~ISIG; /* -isig */
ts.c_lflag &= ~ECHO; /* -echo */
ts.c_cc[VMIN] = 1; /* min 1 */
-
+
err = tcsetattr(STDOUT_FILENO, TCSANOW, &ts);
-
+
if(err == -1) { /* TODO: handle errno */
RET(Qfalse);
}
@@ -3331,6 +3345,39 @@ class ShotgunPrimitives
CODE
end
+ def opt_push_literal
+ <<-CODE
+ OBJECT lits;
+
+ lits = cmethod_get_literals(msg->method);
+ RET(fast_fetch(lits, 0));
+ CODE
+ end
+
+ def opt_push_self
+ <<-CODE
+ RET(msg->recv);
+ CODE
+ end
+
+ def opt_push_ivar
+ <<-CODE
+ OBJECT lits;
+
+ lits = cmethod_get_literals(msg->method);
+ RET(object_get_ivar(state, msg->recv, fast_fetch(lits, 0)));
+ CODE
+ end
+
+ def opt_push_my_field
+ <<-CODE
+ OBJECT lits;
+
+ lits = cmethod_get_literals(msg->method);
+ RET(NTH_FIELD(msg->recv, N2I(fast_fetch(lits, 0))));
+ CODE
+ end
+
end
prim = ShotgunPrimitives.new
diff --git a/shotgun/lib/selector.c b/shotgun/lib/selector.c
index 8a0b71c..0e621a3 100644
--- a/shotgun/lib/selector.c
+++ b/shotgun/lib/selector.c
@@ -50,7 +50,7 @@ void selector_clear(STATE, OBJECT self) {
for(i = 0; i < sz; i++) {
ss = array_get(state, ary, i);
- SENDSITE(ss)->lookup = NULL;
+ cpu_initialize_sendsite(state, SENDSITE(ss));
}
}
diff --git a/shotgun/lib/sendsite.c b/shotgun/lib/sendsite.c
index ab2f737..ed9f602 100644
--- a/shotgun/lib/sendsite.c
+++ b/shotgun/lib/sendsite.c
@@ -28,6 +28,8 @@ OBJECT send_site_create(STATE, OBJECT name, send_site_lookup func) {
ss->data1 = ss->data2 = ss->data3 = Qnil;
ss->lookup = func;
+ cpu_initialize_sendsite(state, ss);
+
selector_associate(state, ss->selector, ss_obj);
return ss_obj;
diff --git a/shotgun/lib/sendsite.h b/shotgun/lib/sendsite.h
index 492568a..e832cb0 100644
--- a/shotgun/lib/sendsite.h
+++ b/shotgun/lib/sendsite.h
@@ -1,7 +1,10 @@
+#ifndef RBX_SENDSITE_H
+#define RBX_SENDSITE_H
+
typedef struct send_site _send_site;
-typedef int (*send_site_lookup)(STATE, cpu c, _send_site *ss, struct message *msg);
+typedef void (*send_site_lookup)(STATE, cpu c, _send_site *ss, struct message *msg);
struct send_site {
OBJECT name;
@@ -19,11 +22,7 @@ struct send_site {
#define SEND_SITE_OBJECT_FIELDS 5
-#define SEND_SITE_ABORT 0
-#define SEND_SITE_DONE 1
-#define SEND_SITE_RESOLVED 2
-#define SEND_SITE_BYTECODE 3
-
void send_site_init(STATE);
OBJECT send_site_create(STATE, OBJECT name, send_site_lookup func);
+#endif
diff --git a/shotgun/lib/shotgun.h b/shotgun/lib/shotgun.h
index d7fcb43..f14d6e8 100644
--- a/shotgun/lib/shotgun.h
+++ b/shotgun/lib/shotgun.h
@@ -4,7 +4,7 @@
#define INTERNAL_DEBUG 0
#define TRACK_STATS 0
-#define DISABLE_CHECKS 0
+#define DISABLE_CHECKS 1
// #define TIME_LOOKUP 1
#include
|