Skip to content
Browse files

Allow allocating dirty objects

In various places we don't have to clear the entire object, for example
because it will be cleared for bytearray's with zeroes anyway, or when
an object copy is immediately created. This allows for allocation
methods that give back these dirty objects to prevent having to set data
twice.
  • Loading branch information...
1 parent c6941a4 commit 8c11e951132eb0b0794f3543a022a494c04c09ce @dbussink dbussink committed
Showing with 71 additions and 19 deletions.
  1. +2 −2 vm/builtin/bytearray.cpp
  2. +1 −1 vm/builtin/compiledcode.cpp
  3. +1 −1 vm/builtin/object.cpp
  4. +1 −1 vm/builtin/string.cpp
  5. +24 −10 vm/objectmemory.cpp
  6. +21 −0 vm/objectmemory.hpp
  7. +5 −0 vm/state.hpp
  8. +9 −4 vm/vm.cpp
  9. +7 −0 vm/vm.hpp
View
4 vm/builtin/bytearray.cpp
@@ -30,7 +30,7 @@ namespace rubinius {
}
size_t body = bytes;
- ByteArray* ba = state->vm()->new_object_bytes<ByteArray>(G(bytearray), body);
+ ByteArray* ba = state->vm()->new_object_bytes_dirty<ByteArray>(G(bytearray), body);
if(unlikely(!ba)) {
Exception::memory_error(state);
@@ -47,7 +47,7 @@ namespace rubinius {
}
size_t body = bytes;
- ByteArray* ba = state->memory()->new_object_bytes_mature<ByteArray>(state, G(bytearray), body);
+ ByteArray* ba = state->memory()->new_object_bytes_mature_dirty<ByteArray>(state, G(bytearray), body);
if(unlikely(!ba)) {
Exception::memory_error(state);
}
View
2 vm/builtin/compiledcode.cpp
@@ -61,7 +61,7 @@ namespace rubinius {
}
CompiledCode* CompiledCode::dup(STATE) {
- CompiledCode* code = CompiledCode::create(state);
+ CompiledCode* code = state->new_object_dirty<CompiledCode>(G(compiled_code));
code->copy_object(state, this);
code->set_executor(CompiledCode::default_executor);
View
2 vm/builtin/object.cpp
@@ -53,7 +53,7 @@ namespace rubinius {
Object* Object::duplicate(STATE) {
if(!reference_p()) return this;
- Object* other = state->vm()->new_object_typed(
+ Object* other = state->vm()->new_object_typed_dirty(
class_object(state), this->total_size(state->vm()), type_id());
return other->copy_object(state, this);
}
View
2 vm/builtin/string.cpp
@@ -782,7 +782,7 @@ namespace rubinius {
}
}
- String* so = state->new_object<String>(cls);
+ String* so = state->new_object_dirty<String>(cls);
so->copy_object(state, this);
so->shared(state, cTrue);
View
34 vm/objectmemory.cpp
@@ -776,7 +776,6 @@ namespace rubinius {
}
#endif
- obj->clear_fields(bytes);
return obj;
}
@@ -805,11 +804,10 @@ namespace rubinius {
}
#endif
- obj->clear_fields(bytes);
return obj;
}
- Object* ObjectMemory::new_object_typed(STATE, Class* cls, size_t bytes, object_type type) {
+ Object* ObjectMemory::new_object_typed_dirty(STATE, Class* cls, size_t bytes, object_type type) {
utilities::thread::SpinLock::LockGuard guard(allocation_lock_);
Object* obj;
@@ -818,13 +816,19 @@ namespace rubinius {
if(unlikely(!obj)) return NULL;
obj->klass(this, cls);
-
+ obj->ivars(this, cNil);
obj->set_obj_type(type);
return obj;
}
- Object* ObjectMemory::new_object_typed_mature(STATE, Class* cls, size_t bytes, object_type type) {
+ Object* ObjectMemory::new_object_typed(STATE, Class* cls, size_t bytes, object_type type) {
+ Object* obj = new_object_typed_dirty(state, cls, bytes, type);
+ obj->clear_fields(bytes);
+ return obj;
+ }
+
+ Object* ObjectMemory::new_object_typed_mature_dirty(STATE, Class* cls, size_t bytes, object_type type) {
utilities::thread::SpinLock::LockGuard guard(allocation_lock_);
Object* obj;
@@ -833,12 +837,18 @@ namespace rubinius {
if(unlikely(!obj)) return NULL;
obj->klass(this, cls);
-
+ obj->ivars(this, cNil);
obj->set_obj_type(type);
return obj;
}
+ Object* ObjectMemory::new_object_typed_mature(STATE, Class* cls, size_t bytes, object_type type) {
+ Object* obj = new_object_typed_mature_dirty(state, cls, bytes, type);
+ obj->clear_fields(bytes);
+ return obj;
+ }
+
/* ONLY use to create Class, the first object. */
Object* ObjectMemory::allocate_object_raw(size_t bytes) {
@@ -848,7 +858,7 @@ namespace rubinius {
return obj;
}
- Object* ObjectMemory::new_object_typed_enduring(STATE, Class* cls, size_t bytes, object_type type) {
+ Object* ObjectMemory::new_object_typed_enduring_dirty(STATE, Class* cls, size_t bytes, object_type type) {
utilities::thread::SpinLock::LockGuard guard(allocation_lock_);
Object* obj = mark_sweep_->allocate(bytes, &collect_mature_now);
@@ -862,15 +872,19 @@ namespace rubinius {
}
#endif
- obj->clear_fields(bytes);
-
obj->klass(this, cls);
-
+ obj->ivars(this, cNil);
obj->set_obj_type(type);
return obj;
}
+ Object* ObjectMemory::new_object_typed_enduring(STATE, Class* cls, size_t bytes, object_type type) {
+ Object* obj = new_object_typed_enduring_dirty(state, cls, bytes, type);
+ obj->clear_fields(bytes);
+ return obj;
+ }
+
TypeInfo* ObjectMemory::find_type_info(Object* obj) {
return type_info[obj->type_id()];
}
View
21 vm/objectmemory.hpp
@@ -275,11 +275,24 @@ namespace rubinius {
void on_fork(STATE);
+ Object* new_object_typed_dirty(STATE, Class* cls, size_t bytes, object_type type);
Object* new_object_typed(STATE, Class* cls, size_t bytes, object_type type);
+
+ Object* new_object_typed_mature_dirty(STATE, Class* cls, size_t bytes, object_type type);
Object* new_object_typed_mature(STATE, Class* cls, size_t bytes, object_type type);
+
+ Object* new_object_typed_enduring_dirty(STATE, Class* cls, size_t bytes, object_type type);
Object* new_object_typed_enduring(STATE, Class* cls, size_t bytes, object_type type);
template <class T>
+ T* new_object_bytes_dirty(STATE, Class* cls, size_t& bytes) {
+ bytes = ObjectHeader::align(sizeof(T) + bytes);
+ T* obj = static_cast<T*>(new_object_typed_dirty(state, cls, bytes, T::type));
+
+ return obj;
+ }
+
+ template <class T>
T* new_object_bytes(STATE, Class* cls, size_t& bytes) {
bytes = ObjectHeader::align(sizeof(T) + bytes);
T* obj = static_cast<T*>(new_object_typed(state, cls, bytes, T::type));
@@ -288,6 +301,14 @@ namespace rubinius {
}
template <class T>
+ T* new_object_bytes_mature_dirty(STATE, Class* cls, size_t& bytes) {
+ bytes = ObjectHeader::align(sizeof(T) + bytes);
+ T* obj = static_cast<T*>(new_object_typed_mature_dirty(state, cls, bytes, T::type));
+
+ return obj;
+ }
+
+ template <class T>
T* new_object_bytes_mature(STATE, Class* cls, size_t& bytes) {
bytes = ObjectHeader::align(sizeof(T) + bytes);
T* obj = static_cast<T*>(new_object_typed_mature(state, cls, bytes, T::type));
View
5 vm/state.hpp
@@ -63,6 +63,11 @@ namespace rubinius {
return static_cast<T*>(vm_->new_object_typed(cls, sizeof(T), T::type));
}
+ template <class T>
+ T* new_object_dirty(Class *cls) {
+ return static_cast<T*>(vm_->new_object_typed_dirty(cls, sizeof(T), T::type));
+ }
+
ThreadState* thread_state() {
return vm_->thread_state();
}
View
13 vm/vm.cpp
@@ -178,11 +178,11 @@ namespace rubinius {
ManagedThread::set_current(vm, name);
}
- Object* VM::new_object_typed(Class* cls, size_t size, object_type type) {
+ Object* VM::new_object_typed_dirty(Class* cls, size_t size, object_type type) {
State state(this);
if(unlikely(size > om->large_object_threshold)) {
- return om->new_object_typed_enduring(&state, cls, size, type);
+ return om->new_object_typed_enduring_dirty(&state, cls, size, type);
}
Object* obj = local_slab().allocate(size).as<Object>();
@@ -195,16 +195,21 @@ namespace rubinius {
// If refill_slab fails, obj will still be NULL.
if(!obj) {
- return om->new_object_typed(&state, cls, size, type);
+ return om->new_object_typed_dirty(&state, cls, size, type);
}
}
obj->init_header(cls, YoungObjectZone, type);
- obj->clear_fields(size);
return obj;
}
+ Object* VM::new_object_typed(Class* cls, size_t size, object_type type) {
+ Object* obj = new_object_typed_dirty(cls, size, type);
+ obj->clear_fields(size);
+ return obj;
+ }
+
Tuple* VM::new_young_tuple_dirty(size_t fields) {
size_t bytes = sizeof(Tuple) + (sizeof(Object*) * fields);
View
7 vm/vm.hpp
@@ -319,6 +319,7 @@ namespace rubinius {
void set_current_fiber(Fiber* fib);
+ Object* new_object_typed_dirty(Class* cls, size_t bytes, object_type type);
Object* new_object_typed(Class* cls, size_t bytes, object_type type);
Object* new_object_typed_mature(Class* cls, size_t bytes, object_type type);
@@ -333,6 +334,12 @@ namespace rubinius {
}
template <class T>
+ T* new_object_bytes_dirty(Class* cls, size_t& bytes) {
+ bytes = ObjectHeader::align(sizeof(T) + bytes);
+ return static_cast<T*>(new_object_typed_dirty(cls, bytes, T::type));
+ }
+
+ template <class T>
T* new_object_bytes(Class* cls, size_t& bytes) {
bytes = ObjectHeader::align(sizeof(T) + bytes);
return static_cast<T*>(new_object_typed(cls, bytes, T::type));

0 comments on commit 8c11e95

Please sign in to comment.
Something went wrong with that request. Please try again.