You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
GDScript: Replace ptrcalls on MethodBind to validated calls
This improves the performance of typed calls to engine methods when the argument types are exact. Using validated calls delegate more of the work the core instead of doing argument unpacking in the VM. It also does not need different instructions for each return type, simplifying the code.
This commit is contained in:
@@ -400,7 +400,6 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
|
||||
}
|
||||
function->_stack_size = RESERVED_STACK + max_locals + temporaries.size();
|
||||
function->_instruction_args_size = instr_args_max;
|
||||
function->_ptrcall_args_size = ptrcall_max;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
function->operator_names = operator_names;
|
||||
@@ -1225,75 +1224,35 @@ void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target,
|
||||
ct.cleanup();
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
|
||||
#define CASE_TYPE(m_type) \
|
||||
case Variant::m_type: \
|
||||
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_PTRCALL_##m_type, 2 + p_arguments.size()); \
|
||||
break
|
||||
void GDScriptByteCodeGenerator::write_call_method_bind_validated(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
|
||||
Variant::Type return_type = Variant::NIL;
|
||||
bool has_return = p_method->has_return();
|
||||
|
||||
bool is_ptrcall = true;
|
||||
|
||||
if (p_method->has_return()) {
|
||||
MethodInfo info;
|
||||
ClassDB::get_method_info(p_method->get_instance_class(), p_method->get_name(), &info);
|
||||
switch (info.return_val.type) {
|
||||
CASE_TYPE(BOOL);
|
||||
CASE_TYPE(INT);
|
||||
CASE_TYPE(FLOAT);
|
||||
CASE_TYPE(STRING);
|
||||
CASE_TYPE(VECTOR2);
|
||||
CASE_TYPE(VECTOR2I);
|
||||
CASE_TYPE(RECT2);
|
||||
CASE_TYPE(RECT2I);
|
||||
CASE_TYPE(VECTOR3);
|
||||
CASE_TYPE(VECTOR3I);
|
||||
CASE_TYPE(TRANSFORM2D);
|
||||
CASE_TYPE(PLANE);
|
||||
CASE_TYPE(AABB);
|
||||
CASE_TYPE(BASIS);
|
||||
CASE_TYPE(TRANSFORM3D);
|
||||
CASE_TYPE(COLOR);
|
||||
CASE_TYPE(STRING_NAME);
|
||||
CASE_TYPE(NODE_PATH);
|
||||
CASE_TYPE(RID);
|
||||
CASE_TYPE(QUATERNION);
|
||||
CASE_TYPE(OBJECT);
|
||||
CASE_TYPE(CALLABLE);
|
||||
CASE_TYPE(SIGNAL);
|
||||
CASE_TYPE(DICTIONARY);
|
||||
CASE_TYPE(ARRAY);
|
||||
CASE_TYPE(PACKED_BYTE_ARRAY);
|
||||
CASE_TYPE(PACKED_INT32_ARRAY);
|
||||
CASE_TYPE(PACKED_INT64_ARRAY);
|
||||
CASE_TYPE(PACKED_FLOAT32_ARRAY);
|
||||
CASE_TYPE(PACKED_FLOAT64_ARRAY);
|
||||
CASE_TYPE(PACKED_STRING_ARRAY);
|
||||
CASE_TYPE(PACKED_VECTOR2_ARRAY);
|
||||
CASE_TYPE(PACKED_VECTOR3_ARRAY);
|
||||
CASE_TYPE(PACKED_COLOR_ARRAY);
|
||||
default:
|
||||
append_opcode_and_argcount(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL_METHOD_BIND : GDScriptFunction::OPCODE_CALL_METHOD_BIND_RET, 2 + p_arguments.size());
|
||||
is_ptrcall = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_PTRCALL_NO_RETURN, 2 + p_arguments.size());
|
||||
if (has_return) {
|
||||
PropertyInfo return_info = p_method->get_return_info();
|
||||
return_type = return_info.type;
|
||||
}
|
||||
|
||||
CallTarget ct = get_call_target(p_target, return_type);
|
||||
|
||||
if (has_return) {
|
||||
Variant::Type temp_type = temporaries[ct.target.address].type;
|
||||
if (temp_type != return_type) {
|
||||
write_type_adjust(ct.target, return_type);
|
||||
}
|
||||
}
|
||||
|
||||
GDScriptFunction::Opcode code = p_method->has_return() ? GDScriptFunction::OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN : GDScriptFunction::OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN;
|
||||
append_opcode_and_argcount(code, 2 + p_arguments.size());
|
||||
|
||||
for (int i = 0; i < p_arguments.size(); i++) {
|
||||
append(p_arguments[i]);
|
||||
}
|
||||
append(p_base);
|
||||
CallTarget ct = get_call_target(p_target);
|
||||
append(ct.target);
|
||||
append(p_arguments.size());
|
||||
append(p_method);
|
||||
ct.cleanup();
|
||||
if (is_ptrcall) {
|
||||
alloc_ptrcall(p_arguments.size());
|
||||
}
|
||||
|
||||
#undef CASE_TYPE
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
|
||||
|
||||
Reference in New Issue
Block a user