Skip to content

Commit

Permalink
[src] Optimized Class inspect_str hash cloning.
Browse files Browse the repository at this point in the history
You may now perform shallow clones of hashes with the not-exported
parrot_hash_clone_pruneable() function; Class's inspect_str VTABLE now uses
this instead of cloning the hash manually.  The function may need a better
name, and we may consider exporting it.

This optimization improves Rakudo startup by 3.557% and should improve all
object reflection similarly.

git-svn-id: https://svn.parrot.org/parrot/trunk@47821 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
chromatic committed Jun 25, 2010
1 parent 1f08c2c commit 18787dc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
13 changes: 13 additions & 0 deletions include/parrot/hash.h
Expand Up @@ -365,6 +365,15 @@ Hash * parrot_create_hash(PARROT_INTERP,
__attribute__nonnull__(4)
__attribute__nonnull__(5);

void parrot_hash_clone_prunable(PARROT_INTERP,
ARGIN(const Hash *hash),
ARGOUT(Hash *dest),
int deep)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
FUNC_MODIFIES(*dest);

PARROT_WARN_UNUSED_RESULT
PARROT_PURE_FUNCTION
int PMC_compare(PARROT_INTERP, ARGIN(PMC *a), ARGIN(PMC *b))
Expand Down Expand Up @@ -505,6 +514,10 @@ int STRING_compare_distinct_cs_enc(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(compare) \
, PARROT_ASSERT_ARG(keyhash))
#define ASSERT_ARGS_parrot_hash_clone_prunable __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(hash) \
, PARROT_ASSERT_ARG(dest))
#define ASSERT_ARGS_PMC_compare __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(a) \
Expand Down
13 changes: 12 additions & 1 deletion src/hash.c
Expand Up @@ -1451,6 +1451,14 @@ void
parrot_hash_clone(PARROT_INTERP, ARGIN(const Hash *hash), ARGOUT(Hash *dest))
{
ASSERT_ARGS(parrot_hash_clone)
parrot_hash_clone_prunable(interp, hash, dest, 1);
}

void
parrot_hash_clone_prunable(PARROT_INTERP, ARGIN(const Hash *hash),
ARGOUT(Hash *dest), int deep)
{
ASSERT_ARGS(parrot_hash_clone_prunable)
UINTVAL entries = hash->entries;
UINTVAL i;

Expand All @@ -1474,7 +1482,10 @@ parrot_hash_clone(PARROT_INTERP, ARGIN(const Hash *hash), ARGOUT(Hash *dest))
if (PMC_IS_NULL((PMC *)b->value))
valtmp = (void *)PMCNULL;
else
valtmp = (void *)VTABLE_clone(interp, (PMC*)b->value);
if (deep)
valtmp = (void *)VTABLE_clone(interp, (PMC*)b->value);
else
valtmp = b->value;
break;

default:
Expand Down
12 changes: 5 additions & 7 deletions src/pmc/class.pmc
Expand Up @@ -1112,13 +1112,11 @@ Array of Class PMCs representing the direct parents of this class.
if (found->vtable->base_type == enum_class_Hash) {
/* for Hash return values, create and return a shallow
* clone because the VTABLE_clone does a deep clone */
PMC * const hash = Parrot_pmc_new(INTERP, enum_class_Hash);
PMC * const iter = VTABLE_get_iter(INTERP, found);
while (VTABLE_get_bool(INTERP, iter)) {
STRING * const key = VTABLE_shift_string(INTERP, iter);
PMC * const value = VTABLE_get_pmc_keyed_str(INTERP, found, key);
VTABLE_set_pmc_keyed_str(INTERP, hash, key, value);
}
PMC * const hash = Parrot_pmc_new(INTERP, enum_class_Hash);
Hash *src = VTABLE_get_pointer(interp, found);
Hash *dest = VTABLE_get_pointer(interp, hash);

parrot_hash_clone_prunable(interp, src, dest, 0);

return hash;
}
Expand Down

0 comments on commit 18787dc

Please sign in to comment.