summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Dreßler <verdre@v0yd.nl>2020-10-22 18:49:36 +0200
committerJonas Dreßler <verdre@v0yd.nl>2020-10-22 18:49:36 +0200
commit6aec0972e768dc5d6f028f8d0cd5d2004f75f925 (patch)
tree3ff888db8ba4221e16bff47b11648d7450b5eedd
parenta1d0d5b630e77a773810e45c368a1db5c3702128 (diff)
downloadgjs-wip/verdre/get-string-inside-resolve_impl.tar.gz
gi/wrapperutils: Move gjs_get_string_id() into resolve() implementationswip/verdre/get-string-inside-resolve_impl
Calling gjs_get_string_id() allocates a string, which can be quite expensive and should be avoided in hot-paths. There are some resolve() implementations which don't need the prop_name string and can return without it, most notably the implementation of ObjectPrototype, which has an unresolvable cache. If we hit that cache, there's no need to create the string. So move the call to gjs_get_string_id() into the implementations of resolve() and make sure ObjectPrototype::resolve() avoids calling it in case we hit the unresolvable cache.
-rw-r--r--gi/boxed.cpp13
-rw-r--r--gi/boxed.h2
-rw-r--r--gi/fundamental.cpp15
-rw-r--r--gi/fundamental.h2
-rw-r--r--gi/interface.cpp13
-rw-r--r--gi/interface.h2
-rw-r--r--gi/object.cpp13
-rw-r--r--gi/object.h2
-rw-r--r--gi/union.cpp13
-rw-r--r--gi/union.h2
-rw-r--r--gi/wrapperutils.h13
11 files changed, 57 insertions, 33 deletions
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index ed879406..208b888d 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -50,11 +50,18 @@ BoxedInstance::BoxedInstance(JSContext* cx, JS::HandleObject obj)
// See GIWrapperBase::resolve().
bool BoxedPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
- JS::HandleId, const char* prop_name,
- bool* resolved) {
+ JS::HandleId id, bool* resolved) {
+ JS::UniqueChars prop_name;
+ if (!gjs_get_string_id(cx, id, &prop_name))
+ return false;
+ if (!prop_name) {
+ *resolved = false;
+ return true; // not resolved, but no error
+ }
+
// Look for methods and other class properties
GjsAutoFunctionInfo method_info =
- g_struct_info_find_method(info(), prop_name);
+ g_struct_info_find_method(info(), prop_name.get());
if (!method_info) {
*resolved = false;
return true;
diff --git a/gi/boxed.h b/gi/boxed.h
index 3167711a..98b192a8 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -123,7 +123,7 @@ class BoxedPrototype : public GIWrapperPrototype<BoxedBase, BoxedPrototype,
private:
GJS_JSAPI_RETURN_CONVENTION
bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- const char* prop_name, bool* resolved);
+ bool* resolved);
GJS_JSAPI_RETURN_CONVENTION
bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 5722997d..8e690a46 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -123,11 +123,18 @@ bool FundamentalPrototype::resolve_interface(JSContext* cx,
// See GIWrapperBase::resolve().
bool FundamentalPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
- JS::HandleId, const char* prop_name,
- bool* resolved) {
+ JS::HandleId id, bool* resolved) {
+ JS::UniqueChars prop_name;
+ if (!gjs_get_string_id(cx, id, &prop_name))
+ return false;
+ if (!prop_name) {
+ *resolved = false;
+ return true; // not resolved, but no error
+ }
+
/* We are the prototype, so look for methods and other class properties */
GjsAutoFunctionInfo method_info =
- g_object_info_find_method(info(), prop_name);
+ g_object_info_find_method(info(), prop_name.get());
if (method_info) {
#if GJS_VERBOSE_ENABLE_GI_USAGE
@@ -157,7 +164,7 @@ bool FundamentalPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
*resolved = false;
}
- return resolve_interface(cx, obj, resolved, prop_name);
+ return resolve_interface(cx, obj, resolved, prop_name.get());
}
/*
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 1c814822..d3429783 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -109,7 +109,7 @@ class FundamentalPrototype
GJS_JSAPI_RETURN_CONVENTION
bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- const char* prop_name, bool* resolved);
+ bool* resolved);
// Public API
public:
diff --git a/gi/interface.cpp b/gi/interface.cpp
index 39dfe20e..4c309f50 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -32,8 +32,7 @@ InterfacePrototype::~InterfacePrototype(void) {
// See GIWrapperBase::resolve().
bool InterfacePrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
- JS::HandleId, const char* name,
- bool* resolved) {
+ JS::HandleId id, bool* resolved) {
/* If we have no GIRepository information then this interface was defined
* from within GJS. In that case, it has no properties that need to be
* resolved from within C code, as interfaces cannot inherit. */
@@ -42,8 +41,16 @@ bool InterfacePrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
return true;
}
+ JS::UniqueChars prop_name;
+ if (!gjs_get_string_id(context, id, &prop_name))
+ return false;
+ if (!prop_name) {
+ *resolved = false;
+ return true; // not resolved, but no error
+ }
+
GjsAutoFunctionInfo method_info =
- g_interface_info_find_method(m_info, name);
+ g_interface_info_find_method(m_info, prop_name.get());
if (method_info) {
if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
diff --git a/gi/interface.h b/gi/interface.h
index 512c7762..309207cb 100644
--- a/gi/interface.h
+++ b/gi/interface.h
@@ -91,7 +91,7 @@ class InterfacePrototype
GJS_JSAPI_RETURN_CONVENTION
bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- const char* name, bool* resolved);
+ bool* resolved);
// JS methods
diff --git a/gi/object.cpp b/gi/object.cpp
index fd338090..9d6be712 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -759,14 +759,21 @@ bool ObjectBase::id_is_never_lazy(jsid name, const GjsAtoms& atoms) {
}
bool ObjectPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
- JS::HandleId id, const char* name,
- bool* resolved) {
+ JS::HandleId id, bool* resolved) {
if (m_unresolvable_cache.has(id)) {
*resolved = false;
return true;
}
- if (!uncached_resolve(context, obj, id, name, resolved))
+ JS::UniqueChars prop_name;
+ if (!gjs_get_string_id(context, id, &prop_name))
+ return false;
+ if (!prop_name) {
+ *resolved = false;
+ return true; // not resolved, but no error
+ }
+
+ if (!uncached_resolve(context, obj, id, prop_name.get(), resolved))
return false;
if (!*resolved && !m_unresolvable_cache.putNew(id)) {
diff --git a/gi/object.h b/gi/object.h
index e5614072..3930aebc 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -274,7 +274,7 @@ class ObjectPrototype
private:
GJS_JSAPI_RETURN_CONVENTION
bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- const char* prop_name, bool* resolved);
+ bool* resolved);
GJS_JSAPI_RETURN_CONVENTION
bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
diff --git a/gi/union.cpp b/gi/union.cpp
index 207be704..6a01833d 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -42,11 +42,18 @@ UnionInstance::~UnionInstance(void) {
// See GIWrapperBase::resolve().
bool UnionPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
- JS::HandleId, const char* prop_name,
- bool* resolved) {
+ JS::HandleId id, bool* resolved) {
+ JS::UniqueChars prop_name;
+ if (!gjs_get_string_id(context, id, &prop_name))
+ return false;
+ if (!prop_name) {
+ *resolved = false;
+ return true; // not resolved, but no error
+ }
+
// Look for methods and other class properties
GjsAutoFunctionInfo method_info =
- g_union_info_find_method(info(), prop_name);
+ g_union_info_find_method(info(), prop_name.get());
if (method_info) {
#if GJS_VERBOSE_ENABLE_GI_USAGE
diff --git a/gi/union.h b/gi/union.h
index f562af50..b46530bc 100644
--- a/gi/union.h
+++ b/gi/union.h
@@ -55,7 +55,7 @@ class UnionPrototype : public GIWrapperPrototype<UnionBase, UnionPrototype,
GJS_JSAPI_RETURN_CONVENTION
bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
- const char* prop_name, bool* resolved);
+ bool* resolved);
// Overrides GIWrapperPrototype::constructor_nargs().
[[nodiscard]] unsigned constructor_nargs(void) const { return 0; }
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index 89b77342..0ff4efaa 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -417,18 +417,7 @@ class GIWrapperBase {
return true;
}
- // A GObject-introspection lazy property will always be a string, so
- // also bail out if trying to resolve an integer or symbol property.
- JS::UniqueChars prop_name;
- if (!gjs_get_string_id(cx, id, &prop_name))
- return false;
- if (!prop_name) {
- *resolved = false;
- return true; // not resolved, but no error
- }
-
- return priv->to_prototype()->resolve_impl(cx, obj, id, prop_name.get(),
- resolved);
+ return priv->to_prototype()->resolve_impl(cx, obj, id, resolved);
}
/*