From 7978f5f73463722f423e2bce8b11a9cf18706884 Mon Sep 17 00:00:00 2001 From: Brian Shirai Date: Sat, 24 Feb 2018 14:59:13 -0800 Subject: [PATCH] Fixed MemoryHeader::get_object_id. --- machine/memory/header.cpp | 2 +- machine/memory/header.hpp | 80 ++++++++++++++++++++++++++--- machine/test/test_memory_header.hpp | 24 ++++++++- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/machine/memory/header.cpp b/machine/memory/header.cpp index ba92302d3f..16f14970f7 100644 --- a/machine/memory/header.cpp +++ b/machine/memory/header.cpp @@ -27,7 +27,7 @@ namespace rubinius { std::atomic MemoryHeader::object_id_counter; void MemoryHeader::bootstrap(STATE) { - object_id_counter = 0; + object_id_counter = 1; } void MemoryHeader::lock(STATE) { diff --git a/machine/memory/header.hpp b/machine/memory/header.hpp index 3f4ed4aaf6..2728421d35 100644 --- a/machine/memory/header.hpp +++ b/machine/memory/header.hpp @@ -357,6 +357,18 @@ Object* const cUndef = reinterpret_cast(0x22L); return (word & type_mask()) == eObjectID; } + uintptr_t get_object_id() const { + if(object_id_p()) { + return reinterpret_cast(word >> value_shift()); + } + + return 0; + } + + void set_object_id(uintptr_t id) { + word = (id << value_shift()) | eObjectID; + } + bool handle_p() const { return (word & type_mask()) == eHandle; } @@ -439,12 +451,20 @@ Object* const cUndef = reinterpret_cast(0x22L); return new(mem) ExtendedHeader(h, eh, eh->size()); } - static ExtendedHeader* create_object_id(const MemoryFlags h) { - return create(h); + static ExtendedHeader* create_object_id(const MemoryFlags h, uintptr_t id) { + ExtendedHeader* nh = create(h); + nh->words[0].set_object_id(id); + + return nh; } - static ExtendedHeader* create_object_id(const MemoryFlags h, const ExtendedHeader* eh) { - return create(h, eh); + static ExtendedHeader* create_object_id( + const MemoryFlags h, const ExtendedHeader* eh, uintptr_t id) + { + ExtendedHeader* nh = create(h, eh); + nh->words[eh->size()].set_object_id(id); + + return nh; } static ExtendedHeader* create_handle(const MemoryFlags h) { @@ -498,6 +518,24 @@ Object* const cUndef = reinterpret_cast(0x22L); return nullptr; } + uintptr_t get_object_id() const { + for(int i = 0; i < size(); i++) { + if(uintptr_t id = words[i].get_object_id()) { + return id; + } + } + + return 0; + } + + void set_object_id(uintptr_t id) { + for(int i = 0; i < size(); i++) { + if(words[i].object_id_p()) { + words[i].set_object_id(id); + } + } + } + uintptr_t get_referenced() const { for(int i = 0; i < size(); i++) { if(uintptr_t refcount = words[i].get_referenced()) { @@ -704,7 +742,7 @@ Object* const cUndef = reinterpret_cast(0x22L); unsigned int referenced() const { if(extended_p()) { ExtendedHeader* eh = extended_header(); - uintptr_t refcount = referenced_field.get(extended_header()->header); + uintptr_t refcount = referenced_field.get(eh->header); if(refcount < max_referenced()) { return refcount; @@ -763,7 +801,24 @@ Object* const cUndef = reinterpret_cast(0x22L); } uintptr_t object_id() const { - return get(object_id_field); + if(extended_p()) { + ExtendedHeader* eh = extended_header(); + uintptr_t id = object_id_field.get(eh->header); + + if(id < max_object_id()) { + return id; + } else { + uintptr_t ext_id = eh->get_object_id(); + + if(ext_id > 0) { + return ext_id; + } else { + return id; + } + } + } else { + return object_id_field.get(header); + } } unsigned int type_specific() const { @@ -795,7 +850,8 @@ Object* const cUndef = reinterpret_cast(0x22L); } else if(id < max_object_id()) { eh = ExtendedHeader::create_copy(object_id_field.set(hh->header, id), hh); } else { - eh = ExtendedHeader::create_object_id(object_id_field.set(hh->header, id), hh); + eh = ExtendedHeader::create_object_id( + object_id_field.set(hh->header, max_object_id()), hh, id); } MemoryFlags nh = extended_flags(eh); @@ -806,10 +862,18 @@ Object* const cUndef = reinterpret_cast(0x22L); } else { if(object_id_field.get(h) > 0) { return object_id_field.get(h); - } else { + } else if(id < max_object_id()) { MemoryFlags nh = object_id_field.set(h, id); if(header.compare_exchange_strong(h, nh)) return id; + } else { + ExtendedHeader* eh = ExtendedHeader::create_object_id( + object_id_field.set(h, max_object_id()), id); + MemoryFlags nh = extended_flags(eh); + + if(header.compare_exchange_strong(h, nh)) return id; + + eh->delete_header(); } } } diff --git a/machine/test/test_memory_header.hpp b/machine/test/test_memory_header.hpp index de52543cae..357b4cdaf1 100644 --- a/machine/test/test_memory_header.hpp +++ b/machine/test/test_memory_header.hpp @@ -42,7 +42,7 @@ class TestMemoryHeader : public CxxTest::TestSuite, public VMTest { h.header = 0x3ffcL; TS_ASSERT_EQUALS(h.thread_id(), 0xfff); - TS_ASSERT_EQUALS(h.max_thread_id(), 0xfff); + TS_ASSERT_EQUALS(MemoryHeader::max_thread_id(), 0xfff); } void test_memory_header_region() { @@ -124,6 +124,10 @@ class TestMemoryHeader : public CxxTest::TestSuite, public VMTest { h.add_reference(); TS_ASSERT_EQUALS(h.referenced(), i+1); + + if(i > 15) { + TS_ASSERT(h.extended_p()); + } } } @@ -175,7 +179,23 @@ class TestMemoryHeader : public CxxTest::TestSuite, public VMTest { h.header = 0x3ffffc0000000000L; TS_ASSERT_EQUALS(h.object_id(), 0xfffffL); - TS_ASSERT_EQUALS(h.max_object_id(), 0xfffffL); + TS_ASSERT_EQUALS(MemoryHeader::max_object_id(), 0xfffffL); + } + + void test_memory_header_set_object_id() { + MemoryHeader::object_id_counter = 21; + + h.get_object_id(); + + TS_ASSERT_EQUALS(h.object_id(), 0x15); + + MemoryHeader::object_id_counter = MemoryHeader::max_object_id() + 10; + + h.header = 0; + h.get_object_id(); + + TS_ASSERT(h.extended_p()); + TS_ASSERT_EQUALS(h.object_id(), MemoryHeader::max_object_id() + 10); } void test_memory_header_type_specific() {