浏览代码

Merge pull request #36189 from reduz/object-id-refactor

Changed logic and optimized ObjectID in ObjectDB and Variant, removed…
Rémi Verschelde 5 年之前
父节点
当前提交
264f20f8c1
共有 51 个文件被更改,包括 432 次插入559 次删除
  1. 6 6
      core/io/marshalls.cpp
  2. 1 1
      core/io/resource_format_binary.cpp
  3. 1 1
      core/io/resource_loader.cpp
  4. 1 1
      core/io/resource_saver.cpp
  5. 115 64
      core/object.cpp
  6. 48 28
      core/object.h
  7. 1 0
      core/object_id.h
  8. 2 2
      core/os/main_loop.cpp
  9. 0 103
      core/ref_ptr.cpp
  10. 0 62
      core/ref_ptr.h
  11. 2 1
      core/reference.cpp
  12. 21 79
      core/reference.h
  13. 0 1
      core/resource.h
  14. 0 18
      core/type_info.h
  15. 95 32
      core/variant.cpp
  16. 7 7
      core/variant.h
  17. 6 16
      core/variant_call.cpp
  18. 32 34
      core/variant_op.cpp
  19. 1 1
      editor/editor_autoload_settings.cpp
  20. 2 2
      editor/editor_data.cpp
  21. 1 1
      editor/editor_node.cpp
  22. 1 1
      editor/import/resource_importer_scene.cpp
  23. 1 1
      editor/plugins/animation_blend_tree_editor_plugin.cpp
  24. 1 1
      editor/plugins/script_editor_plugin.cpp
  25. 1 1
      editor/plugins/version_control_editor_plugin.cpp
  26. 2 2
      editor/plugins/visual_shader_editor_plugin.cpp
  27. 12 14
      editor/property_editor.cpp
  28. 2 2
      editor/scene_tree_dock.cpp
  29. 2 3
      editor/scene_tree_editor.cpp
  30. 1 1
      editor/script_create_dialog.cpp
  31. 1 1
      editor/script_editor_debugger.cpp
  32. 1 1
      main/main.cpp
  33. 0 4
      modules/gdnative/gdnative/gdnative.cpp
  34. 1 1
      modules/gdnative/gdnative/variant.cpp
  35. 0 7
      modules/gdnative/gdnative_api.json
  36. 1 3
      modules/gdnative/include/gdnative/gdnative.h
  37. 5 4
      modules/gdscript/gdscript.cpp
  38. 1 0
      modules/gdscript/gdscript.h
  39. 39 23
      modules/gdscript/gdscript_function.cpp
  40. 4 4
      modules/gdscript/gdscript_function.h
  41. 2 2
      modules/gdscript/gdscript_functions.cpp
  42. 3 3
      modules/mono/csharp_script.cpp
  43. 1 1
      modules/mono/mono_gd/gd_mono_internals.cpp
  44. 2 2
      modules/visual_script/visual_script_editor.cpp
  45. 1 1
      modules/visual_script/visual_script_editor.h
  46. 1 1
      scene/animation/animation_player.cpp
  47. 0 11
      scene/animation/tween.cpp
  48. 1 1
      scene/debugger/script_debugger_remote.cpp
  49. 1 1
      scene/gui/rich_text_label.cpp
  50. 1 1
      scene/resources/font.cpp
  51. 1 1
      scene/resources/resource_format_text.cpp

+ 6 - 6
core/io/marshalls.cpp

@@ -802,10 +802,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 			}
 		} break;
 		case Variant::OBJECT: {
-#ifdef DEBUG_ENABLED
+
 			// Test for potential wrong values sent by the debugger when it breaks.
-			Object *obj = p_variant;
-			if (!obj || !ObjectDB::instance_validate(obj)) {
+			Object *obj = p_variant.get_validated_object();
+			if (!obj) {
 				// Object is invalid, send a NULL instead.
 				if (buf) {
 					encode_uint32(Variant::NIL, buf);
@@ -813,7 +813,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 				r_len += 4;
 				return OK;
 			}
-#endif // DEBUG_ENABLED
+
 			if (!p_full_objects) {
 				flags |= ENCODE_FLAG_OBJECT_AS_ID;
 			}
@@ -1127,9 +1127,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 			} else {
 				if (buf) {
 
-					Object *obj = p_variant;
+					Object *obj = p_variant.get_validated_object();
 					ObjectID id;
-					if (obj && ObjectDB::instance_validate(obj)) {
+					if (obj) {
 						id = obj->get_instance_id();
 					}
 

+ 1 - 1
core/io/resource_format_binary.cpp

@@ -1573,7 +1573,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
 	switch (p_variant.get_type()) {
 		case Variant::OBJECT: {
 
-			RES res = p_variant.operator RefPtr();
+			RES res = p_variant;
 
 			if (res.is_null() || external_resources.has(res))
 				return;

+ 1 - 1
core/io/resource_loader.cpp

@@ -955,7 +955,7 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
 	ERR_FAIL_COND_V_MSG(obj == NULL, false, "Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt) + ".");
 
 	ResourceFormatLoader *crl = Object::cast_to<ResourceFormatLoader>(obj);
-	crl->set_script(s.get_ref_ptr());
+	crl->set_script(s);
 	ResourceLoader::add_resource_format_loader(crl);
 
 	return true;

+ 1 - 1
core/io/resource_saver.cpp

@@ -221,7 +221,7 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
 	ERR_FAIL_COND_V_MSG(obj == NULL, false, "Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt) + ".");
 
 	ResourceFormatSaver *crl = Object::cast_to<ResourceFormatSaver>(obj);
-	crl->set_script(s.get_ref_ptr());
+	crl->set_script(s);
 	ResourceSaver::add_resource_format_saver(crl);
 
 	return true;

+ 115 - 64
core/object.cpp

@@ -968,7 +968,7 @@ void Object::cancel_delete() {
 	_predelete_ok = true;
 }
 
-void Object::set_script_and_instance(const RefPtr &p_script, ScriptInstance *p_instance) {
+void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) {
 
 	//this function is not meant to be used in any of these ways
 	ERR_FAIL_COND(p_script.is_null());
@@ -979,7 +979,7 @@ void Object::set_script_and_instance(const RefPtr &p_script, ScriptInstance *p_i
 	script_instance = p_instance;
 }
 
-void Object::set_script(const RefPtr &p_script) {
+void Object::set_script(const Variant &p_script) {
 
 	if (script == p_script)
 		return;
@@ -990,7 +990,7 @@ void Object::set_script(const RefPtr &p_script) {
 	}
 
 	script = p_script;
-	Ref<Script> s(script);
+	Ref<Script> s = script;
 
 	if (!s.is_null()) {
 		if (s->can_instance()) {
@@ -1017,12 +1017,12 @@ void Object::set_script_instance(ScriptInstance *p_instance) {
 	script_instance = p_instance;
 
 	if (p_instance)
-		script = p_instance->get_script().get_ref_ptr();
+		script = p_instance->get_script();
 	else
-		script = RefPtr();
+		script = Variant();
 }
 
-RefPtr Object::get_script() const {
+Variant Object::get_script() const {
 
 	return script;
 }
@@ -1911,8 +1911,8 @@ void Object::set_script_instance_binding(int p_script_language_index, void *p_da
 	_script_instance_bindings[p_script_language_index] = p_data;
 }
 
-Object::Object() {
-
+void Object::_construct_object(bool p_reference) {
+	type_is_reference = p_reference;
 	_class_ptr = NULL;
 	_block_signals = false;
 	_predelete_ok = 0;
@@ -1933,6 +1933,14 @@ Object::Object() {
 	_lock_index.init(1);
 #endif
 }
+Object::Object(bool p_reference) {
+	_construct_object(p_reference);
+}
+
+Object::Object() {
+
+	_construct_object(false);
+}
 
 Object::~Object() {
 
@@ -1993,96 +2001,139 @@ void postinitialize_handler(Object *p_object) {
 	p_object->_postinitialize();
 }
 
-HashMap<ObjectID, Object *> ObjectDB::instances;
-uint64_t ObjectDB::instance_counter = 1;
-HashMap<Object *, ObjectID, ObjectDB::ObjectPtrHash> ObjectDB::instance_checks;
-ObjectID ObjectDB::add_instance(Object *p_object) {
-
-	ERR_FAIL_COND_V(p_object->get_instance_id().is_valid(), ObjectID());
-
-	rw_lock->write_lock();
-	ObjectID instance_id = ObjectID(++instance_counter);
-	instances[instance_id] = p_object;
-	instance_checks[p_object] = instance_id;
-
-	rw_lock->write_unlock();
+void ObjectDB::debug_objects(DebugFunc p_func) {
 
-	return instance_id;
+	spin_lock.lock();
+	for (uint32_t i = 0; i < slot_count; i++) {
+		uint32_t slot = object_slots[i].next_free;
+		p_func(object_slots[slot].object);
+	}
+	spin_lock.unlock();
 }
 
-void ObjectDB::remove_instance(Object *p_object) {
+void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+}
 
-	rw_lock->write_lock();
+SpinLock ObjectDB::spin_lock;
+uint32_t ObjectDB::slot_count = 0;
+uint32_t ObjectDB::slot_max = 0;
+ObjectDB::ObjectSlot *ObjectDB::object_slots = nullptr;
+uint64_t ObjectDB::validator_counter = 0;
 
-	instances.erase(p_object->get_instance_id());
-	instance_checks.erase(p_object);
+int ObjectDB::get_object_count() {
 
-	rw_lock->write_unlock();
+	return slot_count;
 }
-Object *ObjectDB::get_instance(ObjectID p_instance_id) {
 
-	rw_lock->read_lock();
-	Object **obj = instances.getptr(p_instance_id);
-	rw_lock->read_unlock();
+ObjectID ObjectDB::add_instance(Object *p_object) {
 
-	if (!obj)
-		return NULL;
-	return *obj;
-}
+	spin_lock.lock();
+	if (unlikely(slot_count == slot_max)) {
 
-void ObjectDB::debug_objects(DebugFunc p_func) {
+		CRASH_COND(slot_count == (1 << OBJECTDB_SLOT_MAX_COUNT_BITS));
+
+		uint32_t new_slot_max = slot_max > 0 ? slot_max * 2 : 1;
+		object_slots = (ObjectSlot *)memrealloc(object_slots, sizeof(ObjectSlot) * new_slot_max);
+		for (uint32_t i = slot_max; i < new_slot_max; i++) {
+			object_slots[i].object = nullptr;
+			object_slots[i].is_reference = false;
+			object_slots[i].next_free = i;
+			object_slots[i].validator = 0;
+		}
+		slot_max = new_slot_max;
+	}
 
-	rw_lock->read_lock();
+	uint32_t slot = object_slots[slot_count].next_free;
+	if (object_slots[slot].object != nullptr) {
+		spin_lock.unlock();
+		ERR_FAIL_COND_V(object_slots[slot].object != nullptr, ObjectID());
+	}
+	object_slots[slot].object = p_object;
+	object_slots[slot].is_reference = p_object->is_reference();
+	validator_counter = (validator_counter + 1) & OBJECTDB_VALIDATOR_MASK;
+	if (unlikely(validator_counter == 0)) {
+		validator_counter = 1;
+	}
+	object_slots[slot].validator = validator_counter;
 
-	const ObjectID *K = NULL;
-	while ((K = instances.next(K))) {
+	uint64_t id = validator_counter;
+	id <<= OBJECTDB_SLOT_MAX_COUNT_BITS;
+	id |= uint64_t(slot);
 
-		p_func(instances[*K]);
+	if (p_object->is_reference()) {
+		id |= OBJECTDB_REFERENCE_BIT;
 	}
 
-	rw_lock->read_unlock();
-}
+	slot_count++;
 
-void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+	spin_lock.unlock();
+
+	return ObjectID(id);
 }
 
-int ObjectDB::get_object_count() {
+void ObjectDB::remove_instance(Object *p_object) {
+	uint64_t t = p_object->get_instance_id();
+	uint32_t slot = t & OBJECTDB_SLOT_MAX_COUNT_MASK; //slot is always valid on valid object
 
-	rw_lock->read_lock();
-	int count = instances.size();
-	rw_lock->read_unlock();
+	spin_lock.lock();
 
-	return count;
-}
+#ifdef DEBUG_ENABLED
 
-RWLock *ObjectDB::rw_lock = NULL;
+	if (object_slots[slot].object != p_object) {
+		spin_lock.unlock();
+		ERR_FAIL_COND(object_slots[slot].object != p_object);
+	}
+	{
+		uint64_t validator = (t >> OBJECTDB_SLOT_MAX_COUNT_BITS) & OBJECTDB_VALIDATOR_MASK;
+		if (object_slots[slot].validator != validator) {
+			spin_lock.unlock();
+			ERR_FAIL_COND(object_slots[slot].validator != validator);
+		}
+	}
+
+#endif
+	//decrease slot count
+	slot_count--;
+	//set the free slot properly
+	object_slots[slot_count].next_free = slot;
+	//invalidate, so checks against it fail
+	object_slots[slot].validator = 0;
+	object_slots[slot].is_reference = false;
+	object_slots[slot].object = nullptr;
+
+	spin_lock.unlock();
+}
 
 void ObjectDB::setup() {
 
-	rw_lock = RWLock::create();
+	//nothing to do now
 }
 
 void ObjectDB::cleanup() {
 
-	rw_lock->write_lock();
-	if (instances.size()) {
+	if (slot_count > 0) {
+		spin_lock.lock();
 
 		WARN_PRINT("ObjectDB Instances still exist!");
 		if (OS::get_singleton()->is_stdout_verbose()) {
-			const ObjectID *K = NULL;
-			while ((K = instances.next(K))) {
+			for (uint32_t i = 0; i < slot_count; i++) {
+				uint32_t slot = object_slots[i].next_free;
+				Object *obj = object_slots[slot].object;
 
 				String node_name;
-				if (instances[*K]->is_class("Node"))
-					node_name = " - Node name: " + String(instances[*K]->call("get_name"));
-				if (instances[*K]->is_class("Resource"))
-					node_name = " - Resource name: " + String(instances[*K]->call("get_name")) + " Path: " + String(instances[*K]->call("get_path"));
-				print_line("Leaked instance: " + String(instances[*K]->get_class()) + ":" + itos(*K) + node_name);
+				if (obj->is_class("Node"))
+					node_name = " - Node name: " + String(obj->call("get_name"));
+				if (obj->is_class("Resource"))
+					node_name = " - Resource name: " + String(obj->call("get_name")) + " Path: " + String(obj->call("get_path"));
+
+				uint64_t id = uint64_t(slot) | (uint64_t(object_slots[slot].validator) << OBJECTDB_VALIDATOR_BITS) | (object_slots[slot].is_reference ? OBJECTDB_REFERENCE_BIT : 0);
+				print_line("Leaked instance: " + String(obj->get_class()) + ":" + itos(id) + node_name);
 			}
 		}
+		spin_lock.unlock();
+	}
+
+	if (object_slots) {
+		memfree(object_slots);
 	}
-	instances.clear();
-	instance_checks.clear();
-	rw_lock->write_unlock();
-	memdelete(rw_lock);
 }

+ 48 - 28
core/object.h

@@ -37,6 +37,7 @@
 #include "core/object_id.h"
 #include "core/os/rw_lock.h"
 #include "core/set.h"
+#include "core/spin_lock.h"
 #include "core/variant.h"
 #include "core/vmap.h"
 
@@ -488,7 +489,7 @@ private:
 	Set<String> editor_section_folding;
 #endif
 	ScriptInstance *script_instance;
-	RefPtr script;
+	Variant script; //reference does not yet exist, store it in a
 	Dictionary metadata;
 	mutable StringName _class_name;
 	mutable const StringName *_class_ptr;
@@ -506,9 +507,13 @@ private:
 
 	void property_list_changed_notify();
 
+	_FORCE_INLINE_ void _construct_object(bool p_reference);
+
 	friend class Reference;
+	bool type_is_reference = false;
 	uint32_t instance_binding_count;
 	void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
+	Object(bool p_reference);
 
 protected:
 	virtual void _initialize_classv() { initialize_class(); }
@@ -680,8 +685,8 @@ public:
 
 	/* SCRIPT */
 
-	void set_script(const RefPtr &p_script);
-	RefPtr get_script() const;
+	void set_script(const Variant &p_script);
+	Variant get_script() const;
 
 	/* SCRIPT */
 
@@ -700,7 +705,7 @@ public:
 	void set_script_instance(ScriptInstance *p_instance);
 	_FORCE_INLINE_ ScriptInstance *get_script_instance() const { return script_instance; }
 
-	void set_script_and_instance(const RefPtr &p_script, ScriptInstance *p_instance); //some script languages can't control instance creation, so this function eases the process
+	void set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance); //some script languages can't control instance creation, so this function eases the process
 
 	void add_user_signal(const MethodInfo &p_signal);
 	Error emit_signal(const StringName &p_name, VARIANT_ARG_LIST);
@@ -751,6 +756,7 @@ public:
 
 	void clear_internal_resource_paths();
 
+	_ALWAYS_INLINE_ bool is_reference() const { return type_is_reference; }
 	Object();
 	virtual ~Object();
 };
@@ -760,49 +766,63 @@ void postinitialize_handler(Object *p_object);
 
 class ObjectDB {
 
-	struct ObjectPtrHash {
-
-		static _FORCE_INLINE_ uint32_t hash(const Object *p_obj) {
-
-			union {
-				const Object *p;
-				unsigned long i;
-			} u;
-			u.p = p_obj;
-			return HashMapHasherDefault::hash((uint64_t)u.i);
-		}
+//this needs to add up to 63, 1 bit is for reference
+#define OBJECTDB_VALIDATOR_BITS 39
+#define OBJECTDB_VALIDATOR_MASK ((uint64_t(1) << OBJECTDB_VALIDATOR_BITS) - 1)
+#define OBJECTDB_SLOT_MAX_COUNT_BITS 24
+#define OBJECTDB_SLOT_MAX_COUNT_MASK ((uint64_t(1) << OBJECTDB_SLOT_MAX_COUNT_BITS) - 1)
+#define OBJECTDB_REFERENCE_BIT (uint64_t(1) << (OBJECTDB_SLOT_MAX_COUNT_BITS + OBJECTDB_VALIDATOR_BITS))
+
+	struct ObjectSlot { //128 bits per slot
+		uint64_t validator : OBJECTDB_VALIDATOR_BITS;
+		uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS;
+		uint64_t is_reference : 1;
+		Object *object;
 	};
 
-	static HashMap<ObjectID, Object *> instances;
-	static HashMap<Object *, ObjectID, ObjectPtrHash> instance_checks;
+	static SpinLock spin_lock;
+	static uint32_t slot_count;
+	static uint32_t slot_max;
+	static ObjectSlot *object_slots;
+	static uint64_t validator_counter;
 
-	static uint64_t instance_counter;
 	friend class Object;
 	friend void unregister_core_types();
-
-	static RWLock *rw_lock;
 	static void cleanup();
+
 	static ObjectID add_instance(Object *p_object);
 	static void remove_instance(Object *p_object);
+
 	friend void register_core_types();
 	static void setup();
 
 public:
 	typedef void (*DebugFunc)(Object *p_obj);
 
-	static Object *get_instance(ObjectID p_instance_id);
-	static void debug_objects(DebugFunc p_func);
-	static int get_object_count();
+	_ALWAYS_INLINE_ static Object *get_instance(ObjectID p_instance_id) {
+
+		uint64_t id = p_instance_id;
+		uint32_t slot = id & OBJECTDB_SLOT_MAX_COUNT_MASK;
+
+		ERR_FAIL_COND_V(slot >= slot_max, nullptr); //this should never happen unless RID is corrupted
+
+		spin_lock.lock();
 
-	_FORCE_INLINE_ static bool instance_validate(Object *p_ptr) {
-		rw_lock->read_lock();
+		uint64_t validator = (id >> OBJECTDB_SLOT_MAX_COUNT_BITS) & OBJECTDB_VALIDATOR_MASK;
 
-		bool exists = instance_checks.has(p_ptr);
+		if (unlikely(object_slots[slot].validator != validator)) {
+			spin_lock.unlock();
+			return nullptr;
+		}
+
+		Object *object = object_slots[slot].object;
 
-		rw_lock->read_unlock();
+		spin_lock.unlock();
 
-		return exists;
+		return object;
 	}
+	static void debug_objects(DebugFunc p_func);
+	static int get_object_count();
 };
 
 //needed by macros

+ 1 - 0
core/object_id.h

@@ -12,6 +12,7 @@ class ObjectID {
 	uint64_t id = 0;
 
 public:
+	_ALWAYS_INLINE_ bool is_reference() const { return (id & (uint64_t(1) << 63)) != 0; }
 	_ALWAYS_INLINE_ bool is_valid() const { return id != 0; }
 	_ALWAYS_INLINE_ bool is_null() const { return id == 0; }
 	_ALWAYS_INLINE_ operator uint64_t() const { return id; }

+ 2 - 2
core/os/main_loop.cpp

@@ -95,7 +95,7 @@ void MainLoop::input_event(const Ref<InputEvent> &p_event) {
 void MainLoop::init() {
 
 	if (init_script.is_valid())
-		set_script(init_script.get_ref_ptr());
+		set_script(init_script);
 
 	if (get_script_instance())
 		get_script_instance()->call("_initialize");
@@ -131,6 +131,6 @@ void MainLoop::finish() {
 
 	if (get_script_instance()) {
 		get_script_instance()->call("_finalize");
-		set_script(RefPtr()); //clear script
+		set_script(Variant()); //clear script
 	}
 }

+ 0 - 103
core/ref_ptr.cpp

@@ -1,103 +0,0 @@
-/*************************************************************************/
-/*  ref_ptr.cpp                                                          */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "ref_ptr.h"
-
-#include "core/reference.h"
-#include "core/resource.h"
-
-void RefPtr::operator=(const RefPtr &p_other) {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0]));
-
-	*ref = *ref_other;
-}
-
-bool RefPtr::operator==(const RefPtr &p_other) const {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0]));
-
-	return *ref == *ref_other;
-}
-
-bool RefPtr::operator!=(const RefPtr &p_other) const {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0]));
-
-	return *ref != *ref_other;
-}
-
-RefPtr::RefPtr(const RefPtr &p_other) {
-
-	memnew_placement(&data[0], Ref<Reference>);
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	Ref<Reference> *ref_other = reinterpret_cast<Ref<Reference> *>(const_cast<char *>(&p_other.data[0]));
-
-	*ref = *ref_other;
-}
-
-bool RefPtr::is_null() const {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	return ref->is_null();
-}
-
-RID RefPtr::get_rid() const {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	if (ref->is_null())
-		return RID();
-	Resource *res = Object::cast_to<Resource>(ref->ptr());
-	if (res)
-		return res->get_rid();
-	return RID();
-}
-
-void RefPtr::unref() {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	ref->unref();
-}
-
-RefPtr::RefPtr() {
-
-	ERR_FAIL_COND(sizeof(Ref<Reference>) > DATASIZE);
-	memnew_placement(&data[0], Ref<Reference>);
-}
-
-RefPtr::~RefPtr() {
-
-	Ref<Reference> *ref = reinterpret_cast<Ref<Reference> *>(&data[0]);
-	ref->~Ref<Reference>();
-}

+ 0 - 62
core/ref_ptr.h

@@ -1,62 +0,0 @@
-/*************************************************************************/
-/*  ref_ptr.h                                                            */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef REF_PTR_H
-#define REF_PTR_H
-/**
-	@author Juan Linietsky <[email protected]>
- * This class exists to workaround a limitation in C++ but keep the design OK.
- * It's basically an opaque container of a Reference reference, so Variant can use it.
-*/
-
-#include "core/rid.h"
-
-class RefPtr {
-
-	enum {
-
-		DATASIZE = sizeof(void *) //*4 -ref was shrunk
-	};
-
-	mutable char data[DATASIZE]; // too much probably, virtual class + pointer
-public:
-	bool is_null() const;
-	void operator=(const RefPtr &p_other);
-	bool operator==(const RefPtr &p_other) const;
-	bool operator!=(const RefPtr &p_other) const;
-	RID get_rid() const;
-	void unref();
-	_FORCE_INLINE_ void *get_data() const { return data; }
-	RefPtr(const RefPtr &p_other);
-	RefPtr();
-	~RefPtr();
-};
-
-#endif // REF_PTR_H

+ 2 - 1
core/reference.cpp

@@ -102,7 +102,8 @@ bool Reference::unreference() {
 	return die;
 }
 
-Reference::Reference() {
+Reference::Reference() :
+		Object(true) {
 
 	refcount.init();
 	refcount_init.init();

+ 21 - 79
core/reference.h

@@ -33,7 +33,6 @@
 
 #include "core/class_db.h"
 #include "core/object.h"
-#include "core/ref_ptr.h"
 #include "core/safe_refcount.h"
 
 class Reference : public Object {
@@ -133,17 +132,9 @@ public:
 		return reference;
 	}
 
-	RefPtr get_ref_ptr() const {
-
-		RefPtr refptr;
-		Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(refptr.get_data());
-		*irr = *this;
-		return refptr;
-	};
-
 	operator Variant() const {
 
-		return Variant(get_ref_ptr());
+		return Variant(reference);
 	}
 
 	void operator=(const Ref &p_from) {
@@ -165,33 +156,24 @@ public:
 		r.reference = NULL;
 	}
 
-	void operator=(const RefPtr &p_refptr) {
+	void operator=(const Variant &p_variant) {
 
-		Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(p_refptr.get_data());
-		Reference *refb = irr->ptr();
-		if (!refb) {
-			unref();
+		Object *object = p_variant.get_validated_object();
+
+		if (object == reference) {
 			return;
 		}
-		Ref r;
-		r.reference = Object::cast_to<T>(refb);
-		ref(r);
-		r.reference = NULL;
-	}
 
-	void operator=(const Variant &p_variant) {
+		unref();
 
-		RefPtr refptr = p_variant;
-		Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(refptr.get_data());
-		Reference *refb = irr->ptr();
-		if (!refb) {
-			unref();
+		if (!object) {
 			return;
 		}
-		Ref r;
-		r.reference = Object::cast_to<T>(refb);
-		ref(r);
-		r.reference = NULL;
+
+		Reference *r = Object::cast_to<Reference>(object);
+		if (r && r->reference()) {
+			reference = static_cast<T *>(r);
+		}
 	}
 
 	template <class T_Other>
@@ -237,33 +219,19 @@ public:
 
 	Ref(const Variant &p_variant) {
 
-		RefPtr refptr = p_variant;
-		Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(refptr.get_data());
-		reference = NULL;
-		Reference *refb = irr->ptr();
-		if (!refb) {
-			unref();
+		Object *object = p_variant.get_validated_object();
+
+		if (!object) {
+			reference = nullptr;
 			return;
 		}
-		Ref r;
-		r.reference = Object::cast_to<T>(refb);
-		ref(r);
-		r.reference = NULL;
-	}
-
-	Ref(const RefPtr &p_refptr) {
 
-		Ref<Reference> *irr = reinterpret_cast<Ref<Reference> *>(p_refptr.get_data());
-		reference = NULL;
-		Reference *refb = irr->ptr();
-		if (!refb) {
-			unref();
-			return;
+		Reference *r = Object::cast_to<Reference>(object);
+		if (r && r->reference()) {
+			reference = static_cast<T *>(r);
+		} else {
+			reference = nullptr;
 		}
-		Ref r;
-		r.reference = Object::cast_to<T>(refb);
-		ref(r);
-		r.reference = NULL;
 	}
 
 	inline bool is_valid() const { return reference != NULL; }
@@ -340,32 +308,6 @@ struct PtrToArg<const Ref<T> &> {
 	}
 };
 
-//this is for RefPtr
-
-template <>
-struct PtrToArg<RefPtr> {
-
-	_FORCE_INLINE_ static RefPtr convert(const void *p_ptr) {
-
-		return Ref<Reference>(const_cast<Reference *>(reinterpret_cast<const Reference *>(p_ptr))).get_ref_ptr();
-	}
-
-	_FORCE_INLINE_ static void encode(RefPtr p_val, const void *p_ptr) {
-
-		Ref<Reference> r = p_val;
-		*(Ref<Reference> *)p_ptr = r;
-	}
-};
-
-template <>
-struct PtrToArg<const RefPtr &> {
-
-	_FORCE_INLINE_ static RefPtr convert(const void *p_ptr) {
-
-		return Ref<Reference>(const_cast<Reference *>(reinterpret_cast<const Reference *>(p_ptr))).get_ref_ptr();
-	}
-};
-
 #endif // PTRCALL_ENABLED
 
 #ifdef DEBUG_METHODS_ENABLED

+ 0 - 1
core/resource.h

@@ -33,7 +33,6 @@
 
 #include "core/class_db.h"
 #include "core/object.h"
-#include "core/ref_ptr.h"
 #include "core/reference.h"
 #include "core/safe_refcount.h"
 #include "core/self_list.h"

+ 0 - 18
core/type_info.h

@@ -169,24 +169,6 @@ MAKE_TYPE_INFO(IP_Address, Variant::STRING)
 class BSP_Tree;
 MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY)
 
-//for RefPtr
-template <>
-struct GetTypeInfo<RefPtr> {
-	static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
-	static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
-	static inline PropertyInfo get_class_info() {
-		return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
-	}
-};
-template <>
-struct GetTypeInfo<const RefPtr &> {
-	static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
-	static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
-	static inline PropertyInfo get_class_info() {
-		return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
-	}
-};
-
 //objectID
 template <>
 struct GetTypeInfo<ObjectID> {

+ 95 - 32
core/variant.cpp

@@ -908,6 +908,14 @@ bool Variant::is_one() const {
 	return false;
 }
 
+bool Variant::is_null() const {
+	if (type == OBJECT && _get_obj().obj) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
 void Variant::reference(const Variant &p_variant) {
 
 	switch (type) {
@@ -999,7 +1007,20 @@ void Variant::reference(const Variant &p_variant) {
 		} break;
 		case OBJECT: {
 
-			memnew_placement(_data._mem, ObjData(p_variant._get_obj()));
+			memnew_placement(_data._mem, ObjData);
+
+			if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
+				Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj);
+				if (!reference->reference()) {
+					_get_obj().obj = nullptr;
+					_get_obj().id = ObjectID();
+					break;
+				}
+			}
+
+			_get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj);
+			_get_obj().id = p_variant._get_obj().id;
+
 		} break;
 		case NODE_PATH: {
 
@@ -1114,8 +1135,15 @@ void Variant::clear() {
 		} break;
 		case OBJECT: {
 
+			if (_get_obj().id.is_reference()) {
+				//we are safe that there is a reference here
+				Reference *reference = static_cast<Reference *>(_get_obj().obj);
+				if (reference->unreference()) {
+					memdelete(reference);
+				}
+			}
 			_get_obj().obj = NULL;
-			_get_obj().ref.unref();
+			_get_obj().id = ObjectID();
 		} break;
 		case _RID: {
 			// not much need probably
@@ -1589,14 +1617,11 @@ String Variant::stringify(List<const void *> &stack) const {
 		case OBJECT: {
 
 			if (_get_obj().obj) {
-#ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
-					//only if debugging!
-					if (!ObjectDB::instance_validate(_get_obj().obj)) {
-						return "[Deleted Object]";
-					};
+
+				if (!_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+					return "[Freed Object]";
 				};
-#endif
+
 				return _get_obj().obj->to_string();
 			} else
 				return "[Object:null]";
@@ -1739,24 +1764,16 @@ Variant::operator NodePath() const {
 		return NodePath();
 }
 
-Variant::operator RefPtr() const {
-
-	if (type == OBJECT)
-		return _get_obj().ref;
-	else
-		return RefPtr();
-}
-
 Variant::operator RID() const {
 
 	if (type == _RID)
 		return *reinterpret_cast<const RID *>(_data._mem);
-	else if (type == OBJECT && !_get_obj().ref.is_null()) {
-		return _get_obj().ref.get_rid();
+	else if (type == OBJECT && _get_obj().obj == nullptr) {
+		return RID();
 	} else if (type == OBJECT && _get_obj().obj) {
 #ifdef DEBUG_ENABLED
 		if (ScriptDebugger::get_singleton()) {
-			ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(_get_obj().obj), RID(), "Invalid pointer (object was deleted).");
+			ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed).");
 		};
 #endif
 		Variant::CallError ce;
@@ -1777,6 +1794,25 @@ Variant::operator Object *() const {
 	else
 		return NULL;
 }
+
+Object *Variant::get_validated_object_with_check(bool &r_previously_freed) const {
+	if (type == OBJECT) {
+		Object *instance = ObjectDB::get_instance(_get_obj().id);
+		r_previously_freed = !instance && _get_obj().id != ObjectID();
+		return instance;
+	} else {
+		r_previously_freed = false;
+		return NULL;
+	}
+}
+
+Object *Variant::get_validated_object() const {
+	if (type == OBJECT)
+		return ObjectDB::get_instance(_get_obj().id);
+	else
+		return NULL;
+}
+
 Variant::operator Node *() const {
 
 	if (type == OBJECT)
@@ -2289,15 +2325,6 @@ Variant::Variant(const NodePath &p_node_path) {
 	memnew_placement(_data._mem, NodePath(p_node_path));
 }
 
-Variant::Variant(const RefPtr &p_resource) {
-
-	type = OBJECT;
-	memnew_placement(_data._mem, ObjData);
-	REF *ref = reinterpret_cast<REF *>(p_resource.get_data());
-	_get_obj().obj = ref->ptr();
-	_get_obj().ref = p_resource;
-}
-
 Variant::Variant(const RID &p_rid) {
 
 	type = _RID;
@@ -2309,7 +2336,24 @@ Variant::Variant(const Object *p_object) {
 	type = OBJECT;
 
 	memnew_placement(_data._mem, ObjData);
-	_get_obj().obj = const_cast<Object *>(p_object);
+
+	if (p_object) {
+
+		if (p_object->is_reference()) {
+			Reference *reference = const_cast<Reference *>(static_cast<const Reference *>(p_object));
+			if (!reference->init_ref()) {
+				_get_obj().obj = nullptr;
+				_get_obj().id = ObjectID();
+				return;
+			}
+		}
+
+		_get_obj().obj = const_cast<Object *>(p_object);
+		_get_obj().id = p_object->get_instance_id();
+	} else {
+		_get_obj().obj = nullptr;
+		_get_obj().id = ObjectID();
+	}
 }
 
 Variant::Variant(const Dictionary &p_dictionary) {
@@ -2620,7 +2664,26 @@ void Variant::operator=(const Variant &p_variant) {
 		} break;
 		case OBJECT: {
 
-			*reinterpret_cast<ObjData *>(_data._mem) = p_variant._get_obj();
+			if (_get_obj().id.is_reference()) {
+				//we are safe that there is a reference here
+				Reference *reference = static_cast<Reference *>(_get_obj().obj);
+				if (reference->unreference()) {
+					memdelete(reference);
+				}
+			}
+
+			if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
+				Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj);
+				if (!reference->reference()) {
+					_get_obj().obj = nullptr;
+					_get_obj().id = ObjectID();
+					break;
+				}
+			}
+
+			_get_obj().obj = const_cast<Object *>(p_variant._get_obj().obj);
+			_get_obj().id = p_variant._get_obj().id;
+
 		} break;
 		case NODE_PATH: {
 
@@ -3131,7 +3194,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
 
 bool Variant::is_ref() const {
 
-	return type == OBJECT && !_get_obj().ref.is_null();
+	return type == OBJECT && _get_obj().id.is_reference();
 }
 
 Vector<Variant> varray() {

+ 7 - 7
core/variant.h

@@ -46,11 +46,9 @@
 #include "core/node_path.h"
 #include "core/object_id.h"
 #include "core/pool_vector.h"
-#include "core/ref_ptr.h"
 #include "core/rid.h"
 #include "core/ustring.h"
 
-class RefPtr;
 class Object;
 class Node; // helper
 class Control; // helper
@@ -128,12 +126,12 @@ private:
 
 	struct ObjData {
 
+		ObjectID id;
 		Object *obj;
-		RefPtr ref;
 	};
 
-	_FORCE_INLINE_ ObjData &_get_obj();
-	_FORCE_INLINE_ const ObjData &_get_obj() const;
+	_ALWAYS_INLINE_ ObjData &_get_obj();
+	_ALWAYS_INLINE_ const ObjData &_get_obj() const;
 
 	union {
 		bool _bool;
@@ -162,6 +160,7 @@ public:
 	bool is_shared() const;
 	bool is_zero() const;
 	bool is_one() const;
+	bool is_null() const;
 
 	operator bool() const;
 	operator signed int() const;
@@ -197,7 +196,6 @@ public:
 
 	operator Color() const;
 	operator NodePath() const;
-	operator RefPtr() const;
 	operator RID() const;
 
 	operator Object *() const;
@@ -235,6 +233,9 @@ public:
 
 	operator IP_Address() const;
 
+	Object *get_validated_object() const;
+	Object *get_validated_object_with_check(bool &r_previously_freed) const;
+
 	Variant(bool p_bool);
 	Variant(signed int p_int); // real one
 	Variant(unsigned int p_int);
@@ -267,7 +268,6 @@ public:
 	Variant(const Transform &p_transform);
 	Variant(const Color &p_color);
 	Variant(const NodePath &p_node_path);
-	Variant(const RefPtr &p_resource);
 	Variant(const RID &p_rid);
 	Variant(const Object *p_object);
 	Variant(const Dictionary &p_dictionary);

+ 6 - 16
core/variant_call.cpp

@@ -1099,12 +1099,9 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
 			return;
 		}
 #ifdef DEBUG_ENABLED
-		if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
-			//only if debugging!
-			if (!ObjectDB::instance_validate(obj)) {
-				r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
-				return;
-			}
+		if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+			r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+			return;
 		}
 
 #endif
@@ -1274,18 +1271,11 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
 bool Variant::has_method(const StringName &p_method) const {
 
 	if (type == OBJECT) {
-		Object *obj = operator Object *();
+		Object *obj = get_validated_object();
 		if (!obj)
 			return false;
-#ifdef DEBUG_ENABLED
-		if (ScriptDebugger::get_singleton()) {
-			if (ObjectDB::instance_validate(obj)) {
-#endif
-				return obj->has_method(p_method);
-#ifdef DEBUG_ENABLED
-			}
-		}
-#endif
+
+		return obj->has_method(p_method);
 	}
 
 	const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type];

+ 32 - 34
core/variant_op.cpp

@@ -1515,7 +1515,7 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
 #ifdef DEBUG_ENABLED
 			if (!_get_obj().obj) {
 				break;
-			} else if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
+			} else if (ScriptDebugger::get_singleton() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
 				break;
 			}
 
@@ -1684,7 +1684,7 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
 				return "Instance base is null.";
 			} else {
 
-				if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
+				if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
 					if (r_valid)
 						*r_valid = false;
 					return "Attempted use of stray pointer object.";
@@ -2172,13 +2172,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
 
 			if (obj) {
 #ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
+				if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
 
-					if (!ObjectDB::instance_validate(obj)) {
-						WARN_PRINT("Attempted use of stray pointer object.");
-						valid = false;
-						return;
-					}
+					WARN_PRINT("Attempted use of previously freed pointer object.");
+					valid = false;
+					return;
 				}
 #endif
 
@@ -2546,12 +2544,10 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
 			if (obj) {
 
 #ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
-					//only if debugging!
-					if (!ObjectDB::instance_validate(obj)) {
-						valid = false;
-						return "Attempted get on stray pointer.";
-					}
+
+				if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+					valid = false;
+					return "Attempted get on previously freed instance.";
 				}
 #endif
 
@@ -2611,15 +2607,14 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
 
 				bool valid = false;
 #ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
-					//only if debugging!
-					if (!ObjectDB::instance_validate(obj)) {
-						if (r_valid) {
-							*r_valid = false;
-						}
-						return true; // Attempted get on stray pointer.
+
+				if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+					if (r_valid) {
+						*r_valid = false;
 					}
+					return true; // Attempted get on stray pointer.
 				}
+
 #endif
 
 				if (p_index.get_type() != Variant::STRING) {
@@ -2883,13 +2878,12 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
 			Object *obj = _get_obj().obj;
 			if (obj) {
 #ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
-					//only if debugging!
-					if (!ObjectDB::instance_validate(obj)) {
-						WARN_PRINT("Attempted get_property list on stray pointer.");
-						return;
-					}
+
+				if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+					WARN_PRINT("Attempted get_property list on previously freed instance.");
+					return;
 				}
+
 #endif
 
 				obj->get_property_list(p_list);
@@ -2961,16 +2955,18 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
 		} break;
 		case OBJECT: {
 
-#ifdef DEBUG_ENABLED
 			if (!_get_obj().obj) {
 				valid = false;
 				return false;
 			}
 
-			if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
+#ifdef DEBUG_ENABLED
+
+			if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
 				valid = false;
 				return false;
 			}
+
 #endif
 			Variant::CallError ce;
 			ce.error = Variant::CallError::CALL_OK;
@@ -3129,16 +3125,18 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
 		} break;
 		case OBJECT: {
 
-#ifdef DEBUG_ENABLED
 			if (!_get_obj().obj) {
 				valid = false;
 				return false;
 			}
 
-			if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
+#ifdef DEBUG_ENABLED
+
+			if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
 				valid = false;
 				return false;
 			}
+
 #endif
 			Variant::CallError ce;
 			ce.error = Variant::CallError::CALL_OK;
@@ -3288,16 +3286,16 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
 		} break;
 		case OBJECT: {
 
-#ifdef DEBUG_ENABLED
 			if (!_get_obj().obj) {
 				r_valid = false;
 				return Variant();
 			}
-
-			if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null() && !ObjectDB::instance_validate(_get_obj().obj)) {
+#ifdef DEBUG_ENABLED
+			if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
 				r_valid = false;
 				return Variant();
 			}
+
 #endif
 			Variant::CallError ce;
 			ce.error = Variant::CallError::CALL_OK;

+ 1 - 1
editor/editor_autoload_settings.cpp

@@ -361,7 +361,7 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
 		ERR_FAIL_COND_V_MSG(obj == NULL, NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + ".");
 
 		n = Object::cast_to<Node>(obj);
-		n->set_script(s.get_ref_ptr());
+		n->set_script(s);
 	}
 
 	ERR_FAIL_COND_V_MSG(!n, NULL, "Path in autoload not a node or script: " + p_path + ".");

+ 2 - 2
editor/editor_data.cpp

@@ -506,7 +506,7 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i
 				if (ob->is_class("Node")) {
 					ob->call("set_name", p_type);
 				}
-				ob->set_script(script.get_ref_ptr());
+				ob->set_script(script);
 				return ob;
 			}
 		}
@@ -907,7 +907,7 @@ Object *EditorData::script_class_instance(const String &p_class) {
 		if (obj) {
 			Ref<Script> script = script_class_load_script(p_class);
 			if (script.is_valid())
-				obj->set_script(script.get_ref_ptr());
+				obj->set_script(script);
 			return obj;
 		}
 	}

+ 1 - 1
editor/editor_node.cpp

@@ -3107,7 +3107,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
 	}
 
 	EditorPlugin *ep = memnew(EditorPlugin);
-	ep->set_script(script.get_ref_ptr());
+	ep->set_script(script);
 	plugin_addons[p_addon] = ep;
 	add_editor_plugin(ep, p_config_changed);
 

+ 1 - 1
editor/import/resource_importer_scene.cpp

@@ -1473,7 +1473,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 		} else {
 
 			post_import_script = Ref<EditorScenePostImport>(memnew(EditorScenePostImport));
-			post_import_script->set_script(scr.get_ref_ptr());
+			post_import_script->set_script(scr);
 			if (!post_import_script->get_script_instance()) {
 				EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):") + " " + post_import_script_path);
 				post_import_script.unref();

+ 1 - 1
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -312,7 +312,7 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
 		AnimationNode *an = Object::cast_to<AnimationNode>(ClassDB::instance(base_type));
 		ERR_FAIL_COND(!an);
 		anode = Ref<AnimationNode>(an);
-		anode->set_script(add_options[p_idx].script.get_ref_ptr());
+		anode->set_script(add_options[p_idx].script);
 		base_name = add_options[p_idx].name;
 	}
 

+ 1 - 1
editor/plugins/script_editor_plugin.cpp

@@ -1257,7 +1257,7 @@ void ScriptEditor::_menu_option(int p_option) {
 				}
 
 				Ref<EditorScript> es = memnew(EditorScript);
-				es->set_script(scr.get_ref_ptr());
+				es->set_script(scr);
 				es->set_editor(EditorNode::get_singleton());
 
 				es->_run();

+ 1 - 1
editor/plugins/version_control_editor_plugin.cpp

@@ -124,7 +124,7 @@ void VersionControlEditorPlugin::_initialize_vcs() {
 	ERR_FAIL_COND_MSG(!addon_script_instance, "Failed to create addon script instance.");
 
 	// The addon is attached as a script to the VCS interface as a proxy end-point
-	vcs_interface->set_script_and_instance(script.get_ref_ptr(), addon_script_instance);
+	vcs_interface->set_script_and_instance(script, addon_script_instance);
 
 	EditorVCSInterface::set_singleton(vcs_interface);
 	EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_refresh_stage_area");

+ 2 - 2
editor/plugins/visual_shader_editor_plugin.cpp

@@ -216,7 +216,7 @@ void VisualShaderEditor::update_custom_nodes() {
 
 			Ref<VisualShaderNodeCustom> ref;
 			ref.instance();
-			ref->set_script(script.get_ref_ptr());
+			ref->set_script(script);
 
 			String name;
 			if (ref->has_method("_get_name")) {
@@ -1415,7 +1415,7 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
 		VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(base_type));
 		ERR_FAIL_COND_V(!vsn, NULL);
 		vsnode = Ref<VisualShaderNode>(vsn);
-		vsnode->set_script(add_options[p_idx].script.get_ref_ptr());
+		vsnode->set_script(add_options[p_idx].script);
 	}
 
 	Point2 position = graph->get_scroll_ofs();

+ 12 - 14
editor/property_editor.cpp

@@ -176,9 +176,9 @@ void CustomPropertyEditor::_menu_option(int p_which) {
 
 				case OBJ_MENU_EDIT: {
 
-					RefPtr RefPtr = v;
+					REF r = v;
 
-					if (!RefPtr.is_null()) {
+					if (!r.is_null()) {
 
 						emit_signal("resource_edit_request");
 						hide();
@@ -193,8 +193,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
 
 				case OBJ_MENU_MAKE_UNIQUE: {
 
-					RefPtr RefPtr = v;
-					Ref<Resource> res_orig = RefPtr;
+					Ref<Resource> res_orig = v;
 					if (res_orig.is_null())
 						return;
 
@@ -229,7 +228,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
 						res->set(p.first, p.second);
 					}
 
-					v = res.get_ref_ptr();
+					v = res;
 					emit_signal("variant_changed");
 					hide();
 				} break;
@@ -311,7 +310,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
 						res->call("set_instance_base_type", owner->get_class());
 					}
 
-					v = Ref<Resource>(res).get_ref_ptr();
+					v = res;
 					emit_signal("variant_changed");
 
 				} break;
@@ -1103,7 +1102,7 @@ void CustomPropertyEditor::_file_selected(String p_file) {
 				error->popup_centered_minsize();
 				break;
 			}
-			v = res.get_ref_ptr();
+			v = res;
 			emit_signal("variant_changed");
 			hide();
 		} break;
@@ -1168,7 +1167,7 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
 		Resource *res = Object::cast_to<Resource>(obj);
 		ERR_FAIL_COND(!res);
 
-		v = Ref<Resource>(res).get_ref_ptr();
+		v = res;
 		emit_signal("variant_changed");
 		hide();
 	}
@@ -1373,7 +1372,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
 					Resource *res = Object::cast_to<Resource>(obj);
 					ERR_BREAK(!res);
 
-					v = Ref<Resource>(res).get_ref_ptr();
+					v = res;
 					emit_signal("variant_changed");
 					hide();
 				}
@@ -1395,9 +1394,9 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
 
 			} else if (p_which == 2) {
 
-				RefPtr RefPtr = v;
+				RES r = v;
 
-				if (!RefPtr.is_null()) {
+				if (!r.is_null()) {
 
 					emit_signal("resource_edit_request");
 					hide();
@@ -1410,8 +1409,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
 				hide();
 			} else if (p_which == 4) {
 
-				RefPtr RefPtr = v;
-				Ref<Resource> res_orig = RefPtr;
+				Ref<Resource> res_orig = v;
 				if (res_orig.is_null())
 					return;
 
@@ -1442,7 +1440,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
 					res->set(p.first, p.second);
 				}
 
-				v = res.get_ref_ptr();
+				v = res;
 				emit_signal("variant_changed");
 				hide();
 			}

+ 2 - 2
editor/scene_tree_dock.cpp

@@ -972,7 +972,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 					new_node = Object::cast_to<Node>(ClassDB::instance(ScriptServer::get_global_class_native_base(name)));
 					Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(name), "Script");
 					if (new_node && script.is_valid()) {
-						new_node->set_script(script.get_ref_ptr());
+						new_node->set_script(script);
 						new_node->set_name(name);
 					}
 				} else {
@@ -1725,7 +1725,7 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
 	for (List<Node *>::Element *E = selected.front(); E; E = E->next()) {
 
 		Ref<Script> existing = E->get()->get_script();
-		editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr());
+		editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script);
 		editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
 		editor_data->get_undo_redo().add_do_method(this, "_update_script_button");
 		editor_data->get_undo_redo().add_undo_method(this, "_update_script_button");

+ 2 - 3
editor/scene_tree_editor.cpp

@@ -70,10 +70,9 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
 			emit_signal("open", n->get_filename());
 		}
 	} else if (p_id == BUTTON_SCRIPT) {
-		RefPtr script = n->get_script();
-		Ref<Script> script_typed = script;
+		Ref<Script> script_typed = n->get_script();
 		if (!script_typed.is_null())
-			emit_signal("open_script", script);
+			emit_signal("open_script", script_typed);
 
 	} else if (p_id == BUTTON_VISIBILITY) {
 		undo_redo->create_action(TTR("Toggle Visible"));

+ 1 - 1
editor/script_create_dialog.cpp

@@ -332,7 +332,7 @@ void ScriptCreateDialog::_load_exist() {
 		return;
 	}
 
-	emit_signal("script_created", p_script.get_ref_ptr());
+	emit_signal("script_created", p_script);
 	hide();
 }
 

+ 1 - 1
editor/script_editor_debugger.cpp

@@ -619,7 +619,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
 
 					if (pinfo.hint_string == "Script") {
 						if (debugObj->get_script() != var) {
-							debugObj->set_script(RefPtr());
+							debugObj->set_script(REF());
 							Ref<Script> script(var);
 							if (!script.is_null()) {
 								ScriptInstance *script_instance = script->placeholder_instance_create(debugObj);

+ 1 - 1
main/main.cpp

@@ -1719,7 +1719,7 @@ bool Main::start() {
 						ERR_CONTINUE_MSG(obj == NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
 
 						n = Object::cast_to<Node>(obj);
-						n->set_script(script_res.get_ref_ptr());
+						n->set_script(script_res);
 					}
 
 					ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + path);

+ 0 - 4
modules/gdnative/gdnative/gdnative.cpp

@@ -166,10 +166,6 @@ void _gdnative_report_loading_error(const godot_object *p_library, const char *p
 	_err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr());
 }
 
-bool GDAPI godot_is_instance_valid(const godot_object *p_object) {
-	return ObjectDB::instance_validate((Object *)p_object);
-}
-
 godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) {
 	return (godot_object *)ObjectDB::get_instance(ObjectID(p_instance_id));
 }

+ 1 - 1
modules/gdnative/gdnative/variant.cpp

@@ -178,7 +178,7 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p
 		ref = REF(reference);
 	}
 	if (!ref.is_null()) {
-		memnew_placement_custom(dest, Variant, Variant(ref.get_ref_ptr()));
+		memnew_placement_custom(dest, Variant, Variant(ref));
 	} else {
 #if defined(DEBUG_METHODS_ENABLED)
 		if (reference) {

+ 0 - 7
modules/gdnative/gdnative_api.json

@@ -403,13 +403,6 @@
             ["const godot_vector3 *", "p_scale"]
           ]
         },
-        {
-          "name": "godot_is_instance_valid",
-          "return_type": "bool",
-          "arguments": [
-            ["const godot_object *", "p_object"]
-          ]
-        },
         {
           "name": "godot_quat_new_with_basis",
           "return_type": "void",

+ 1 - 3
modules/gdnative/include/gdnative/gdnative.h

@@ -282,9 +282,7 @@ void GDAPI godot_print_error(const char *p_description, const char *p_function,
 void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line);
 void GDAPI godot_print(const godot_string *p_message);
 
-// GDNATIVE CORE 1.0.1
-
-bool GDAPI godot_is_instance_valid(const godot_object *p_object);
+// GDNATIVE CORE 1.0.2?
 
 //tags used for safe dynamic casting
 void GDAPI *godot_get_class_tag(const godot_string_name *p_class);

+ 5 - 4
modules/gdscript/gdscript.cpp

@@ -93,6 +93,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
 	instance->members.resize(member_indices.size());
 	instance->script = Ref<GDScript>(this);
 	instance->owner = p_owner;
+	instance->owner_id = p_owner->get_instance_id();
 #ifdef DEBUG_ENABLED
 	//needed for hot reloading
 	for (Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) {
@@ -1792,7 +1793,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
 
 					obj->get_script_instance()->get_property_state(state);
 					map[obj->get_instance_id()] = state;
-					obj->set_script(RefPtr());
+					obj->set_script(Variant());
 				}
 			}
 
@@ -1808,7 +1809,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
 					map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >());
 					List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()];
 					obj->get_script_instance()->get_property_state(state);
-					obj->set_script(RefPtr());
+					obj->set_script(Variant());
 				} else {
 					// no instance found. Let's remove it so we don't loop forever
 					E->get()->placeholders.erase(E->get()->placeholders.front()->get());
@@ -1839,9 +1840,9 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
 
 			if (!p_soft_reload) {
 				//clear it just in case (may be a pending reload state)
-				obj->set_script(RefPtr());
+				obj->set_script(Variant());
 			}
-			obj->set_script(scr.get_ref_ptr());
+			obj->set_script(scr);
 
 			ScriptInstance *script_instance = obj->get_script_instance();
 

+ 1 - 0
modules/gdscript/gdscript.h

@@ -241,6 +241,7 @@ class GDScriptInstance : public ScriptInstance {
 	friend class GDScriptFunctions;
 	friend class GDScriptCompiler;
 
+	ObjectID owner_id;
 	Object *owner;
 	Ref<GDScript> script;
 #ifdef DEBUG_ENABLED

+ 39 - 23
modules/gdscript/gdscript_function.cpp

@@ -137,18 +137,19 @@ static String _get_var_type(const Variant *p_var) {
 	String basestr;
 
 	if (p_var->get_type() == Variant::OBJECT) {
-		Object *bobj = *p_var;
+		bool was_freed;
+		Object *bobj = p_var->get_validated_object_with_check(was_freed);
 		if (!bobj) {
-			basestr = "null instance";
-		} else {
-			if (ObjectDB::instance_validate(bobj)) {
-				if (bobj->get_script_instance())
-					basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
-				else
-					basestr = bobj->get_class();
+			if (was_freed) {
+				basestr = "null instance";
 			} else {
-				basestr = "previously freed instance";
+				basestr = "previously freed";
 			}
+		} else {
+			if (bobj->get_script_instance())
+				basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
+			else
+				basestr = bobj->get_class();
 		}
 
 	} else {
@@ -497,14 +498,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 
 				bool extends_ok = false;
 				if (a->get_type() == Variant::OBJECT && a->operator Object *() != NULL) {
-					Object *obj_A = *a;
-					Object *obj_B = *b;
 
 #ifdef DEBUG_ENABLED
-					if (!ObjectDB::instance_validate(obj_A)) {
-						err_text = "Left operand of 'is' was already freed.";
+					bool was_freed;
+					Object *obj_A = a->get_validated_object_with_check(was_freed);
+
+					if (was_freed) {
+						err_text = "Left operand of 'is' is a previously freed instance.";
 						OPCODE_BREAK;
 					}
+
+					Object *obj_B = b->get_validated_object_with_check(was_freed);
+
+					if (was_freed) {
+						err_text = "Right operand of 'is' is a previously freed instance.";
+						OPCODE_BREAK;
+					}
+#else
+
+					Object *obj_A = *a;
+					Object *obj_B = *b;
 #endif // DEBUG_ENABLED
 
 					GDScript *scr_B = Object::cast_to<GDScript>(obj_B);
@@ -1298,20 +1311,20 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 					}
 #endif
 
-					Object *obj = argobj->operator Object *();
+#ifdef DEBUG_ENABLED
+					bool was_freed;
+					Object *obj = argobj->get_validated_object_with_check(was_freed);
 					String signal = argname->operator String();
 
-#ifdef DEBUG_ENABLED
+					if (was_freed) {
+						err_text = "First argument of yield() is a previously freed instance.";
+						OPCODE_BREAK;
+					}
+
 					if (!obj) {
 						err_text = "First argument of yield() is null.";
 						OPCODE_BREAK;
 					}
-					if (ScriptDebugger::get_singleton()) {
-						if (!ObjectDB::instance_validate(obj)) {
-							err_text = "First argument of yield() is a previously freed instance.";
-							OPCODE_BREAK;
-						}
-					}
 					if (signal.length() == 0) {
 
 						err_text = "Second argument of yield() is an empty string (for signal name).";
@@ -1324,6 +1337,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 						OPCODE_BREAK;
 					}
 #else
+					Object *obj = argobj->operator Object *();
+					String signal = argname->operator String();
+
 					obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
 #endif
 				}
@@ -1565,14 +1581,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 		//error
 		// function, file, line, error, explanation
 		String err_file;
-		if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->path != "")
+		if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "")
 			err_file = p_instance->script->path;
 		else if (script)
 			err_file = script->path;
 		if (err_file == "")
 			err_file = "<built-in>";
 		String err_func = name;
-		if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->name != "")
+		if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "")
 			err_func = p_instance->script->name + "." + err_func;
 		int err_line = line;
 		if (err_text == "") {

+ 4 - 4
modules/gdscript/gdscript_function.h

@@ -77,8 +77,8 @@ struct GDScriptDataType {
 					return false;
 				}
 
-				Object *obj = p_variant.operator Object *();
-				if (!obj || !ObjectDB::instance_validate(obj)) {
+				Object *obj = p_variant.get_validated_object();
+				if (!obj) {
 					return false;
 				}
 
@@ -100,8 +100,8 @@ struct GDScriptDataType {
 					return false;
 				}
 
-				Object *obj = p_variant.operator Object *();
-				if (!obj || !ObjectDB::instance_validate(obj)) {
+				Object *obj = p_variant.get_validated_object();
+				if (!obj) {
 					return false;
 				}
 

+ 2 - 2
modules/gdscript/gdscript_functions.cpp

@@ -1441,8 +1441,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
 			if (p_args[0]->get_type() != Variant::OBJECT) {
 				r_ret = false;
 			} else {
-				Object *obj = *p_args[0];
-				r_ret = ObjectDB::instance_validate(obj);
+				Object *obj = p_args[0]->get_validated_object();
+				r_ret = obj != nullptr;
 			}
 
 		} break;

+ 3 - 3
modules/mono/csharp_script.cpp

@@ -854,7 +854,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
 
 		while (script->instances.front()) {
 			Object *obj = script->instances.front()->get();
-			obj->set_script(RefPtr()); // Remove script and existing script instances (placeholder are not removed before domain reload)
+			obj->set_script(REF()); // Remove script and existing script instances (placeholder are not removed before domain reload)
 		}
 
 		script->_clear();
@@ -877,7 +877,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
 
 				// Use a placeholder for now to avoid losing the state when saving a scene
 
-				obj->set_script(scr.get_ref_ptr());
+				obj->set_script(scr);
 
 				PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
 				obj->set_script_instance(placeholder);
@@ -1003,7 +1003,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
 				CRASH_COND(si != NULL);
 #endif
 				// Re-create script instance
-				obj->set_script(script.get_ref_ptr()); // will create the script instance as well
+				obj->set_script(script); // will create the script instance as well
 			}
 		}
 

+ 1 - 1
modules/mono/mono_gd/gd_mono_internals.cpp

@@ -107,7 +107,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
 
 	ScriptInstance *si = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
 
-	unmanaged->set_script_and_instance(script.get_ref_ptr(), si);
+	unmanaged->set_script_and_instance(script, si);
 }
 
 void unhandled_exception(MonoException *p_exc) {

+ 2 - 2
modules/visual_script/visual_script_editor.cpp

@@ -4963,7 +4963,7 @@ Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_na
 }
 
 _VisualScriptEditor *_VisualScriptEditor::singleton = NULL;
-Map<String, RefPtr> _VisualScriptEditor::custom_nodes;
+Map<String, REF> _VisualScriptEditor::custom_nodes;
 
 _VisualScriptEditor::_VisualScriptEditor() {
 	singleton = this;
@@ -4975,7 +4975,7 @@ _VisualScriptEditor::~_VisualScriptEditor() {
 
 void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
 	String node_name = "custom/" + p_category + "/" + p_name;
-	custom_nodes.insert(node_name, p_script.get_ref_ptr());
+	custom_nodes.insert(node_name, p_script);
 	VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom);
 	emit_signal("custom_nodes_updated");
 }

+ 1 - 1
modules/visual_script/visual_script_editor.h

@@ -341,7 +341,7 @@ protected:
 	static void _bind_methods();
 	static _VisualScriptEditor *singleton;
 
-	static Map<String, RefPtr> custom_nodes;
+	static Map<String, REF> custom_nodes;
 	static Ref<VisualScriptNode> create_node_custom(const String &p_name);
 
 public:

+ 1 - 1
scene/animation/animation_player.cpp

@@ -106,7 +106,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
 	} else if (name.begins_with("anims/")) {
 
 		String which = name.get_slicec('/', 1);
-		r_ret = get_animation(which).get_ref_ptr();
+		r_ret = get_animation(which);
 
 	} else if (name.begins_with("next/")) {
 

+ 0 - 11
scene/animation/tween.cpp

@@ -1227,7 +1227,6 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
 
 	// Give it the object
 	ERR_FAIL_COND_V_MSG(p_object == NULL, false, "Invalid object provided to Tween.");
-	ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(p_object), false, "Invalid object provided to Tween.");
 	data.id = p_object->get_instance_id();
 
 	// Validate the initial and final values
@@ -1328,7 +1327,6 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
 
 	// Check that the target object is valid
 	ERR_FAIL_COND_V(p_object == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
 
 	// Duration cannot be negative
 	ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1387,7 +1385,6 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
 
 	// Check that the target object is valid
 	ERR_FAIL_COND_V(p_object == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
 
 	// No negative durations allowed
 	ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1457,9 +1454,7 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
 
 	// Confirm the source and target objects are valid
 	ERR_FAIL_COND_V(p_object == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
 	ERR_FAIL_COND_V(p_target == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false);
 
 	// No negative durations
 	ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1521,9 +1516,7 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
 
 	// Verify the source and target objects are valid
 	ERR_FAIL_COND_V(p_object == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
 	ERR_FAIL_COND_V(p_target == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false);
 
 	// No negative durations
 	ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1587,9 +1580,7 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
 
 	// Verify both objects are valid
 	ERR_FAIL_COND_V(p_object == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
 	ERR_FAIL_COND_V(p_initial == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false);
 
 	// No negative durations
 	ERR_FAIL_COND_V(p_duration < 0, false);
@@ -1655,9 +1646,7 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
 
 	// Make sure the given objects are valid
 	ERR_FAIL_COND_V(p_object == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
 	ERR_FAIL_COND_V(p_initial == NULL, false);
-	ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false);
 
 	// No negative durations
 	ERR_FAIL_COND_V(p_duration < 0, false);

+ 1 - 1
scene/debugger/script_debugger_remote.cpp

@@ -106,7 +106,7 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_
 	packet_peer_stream->put_var(p_name);
 
 	Variant var = p_variable;
-	if (p_variable.get_type() == Variant::OBJECT && !ObjectDB::instance_validate(p_variable)) {
+	if (p_variable.get_type() == Variant::OBJECT && p_variable.get_validated_object() == nullptr) {
 		var = Variant();
 	}
 

+ 1 - 1
scene/gui/rich_text_label.cpp

@@ -2664,7 +2664,7 @@ void RichTextLabel::set_effects(const Vector<Variant> &effects) {
 Vector<Variant> RichTextLabel::get_effects() {
 	Vector<Variant> r;
 	for (int i = 0; i < custom_effects.size(); i++) {
-		r.push_back(custom_effects[i].get_ref_ptr());
+		r.push_back(custom_effects[i]);
 	}
 	return r;
 }

+ 1 - 1
scene/resources/font.cpp

@@ -192,7 +192,7 @@ Vector<Variant> BitmapFont::_get_textures() const {
 
 	Vector<Variant> rtextures;
 	for (int i = 0; i < textures.size(); i++)
-		rtextures.push_back(textures[i].get_ref_ptr());
+		rtextures.push_back(textures[i]);
 	return rtextures;
 }
 

+ 1 - 1
scene/resources/resource_format_text.cpp

@@ -1377,7 +1377,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
 	switch (p_variant.get_type()) {
 		case Variant::OBJECT: {
 
-			RES res = p_variant.operator RefPtr();
+			RES res = p_variant;
 
 			if (res.is_null() || external_resources.has(res))
 				return;