pool->descriptorsize = size;
if (size) {
+ size += sizeof(Mutex); /* prepend Mutex */
pool->descriptors = MNEW(u1, size);
+ /* call Mutex constructor */
+ new (reinterpret_cast<Mutex*>(pool->descriptors)) Mutex;
+ pool->descriptors += sizeof(Mutex);
pool->descriptors_next = pool->descriptors;
}
assert(d);
md = (methoddesc *) pool->descriptors_next;
+ md->pool_lock = reinterpret_cast<Mutex*>(pool->descriptors - sizeof(Mutex));
pool->descriptors_next += sizeof(methoddesc) - sizeof(typedesc);
utf_ptr = desc->text + 1; /* skip '(' */
md_param_alloc(md);
}
#endif
+
+ /* params already initialized; no need to lock */
+ md->pool_lock = NULL;
}
else {
/* params will be allocated later by
/* descriptor_params_from_paramtypes *******************************************
- Create the paramdescs for a method descriptor. This function is called
- when we know whether the method is static or not. This function may only
- be called once for each methoddesc, and only if md->params == NULL.
+ Create the paramdescs for a method descriptor. This function is
+ called when we know whether the method is static or not. This
+ function does nothing if md->params != NULL (checked atomically).
IN:
md...............the parsed method descriptor
- md->params MUST be NULL.
mflags...........the ACC_* access flags of the method. Only the
ACC_STATIC bit is checked.
The value ACC_UNDEF is NOT allowed.
void descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
{
- typedesc *td;
+ bool has_lock = md->pool_lock;
assert(md);
+ if (md->pool_lock)
+ md->pool_lock->lock();
+ if (md->params) {
+ if (has_lock)
+ md->pool_lock->unlock();
+ return;
+ }
assert(md->params == NULL);
assert(mflags != ACC_UNDEF);
- td = md->paramtypes;
+ typedesc *td = md->paramtypes;
/* check for `this' pointer */
md_param_alloc(md);
}
#endif
+
+ if (has_lock)
+ md->pool_lock->unlock();
}
#endif
s4 memuse; /* number of stack slots used */
paramdesc *params; /* allocated parameter descriptions [3] */
+ Mutex *pool_lock; /* synchronizes access to params */
typedesc returntype; /* parsed descriptor of the return type */
typedesc paramtypes[1]; /* parameter types, variable length! */
};
/* Parse parameters if not done yet. */
- if (md->params == NULL)
- descriptor_params_from_paramtypes(md, opc == BC_invokestatic ? ACC_STATIC : 0);
+ descriptor_params_from_paramtypes(md, opc == BC_invokestatic ? ACC_STATIC : 0);
/* Try to lazyly resolve method. */
md = fmi->parseddesc.md;
- if (md->params == NULL)
- descriptor_params_from_paramtypes(md, ACC_STATIC);
+ descriptor_params_from_paramtypes(md, ACC_STATIC);
goto invoke_method;
md = fmi->parseddesc.md;
- if (md->params == NULL)
- descriptor_params_from_paramtypes(md, 0);
+ descriptor_params_from_paramtypes(md, 0);
invoke_method:
code_unflag_leafmethod(code);
/* allocate parameter descriptors if necessary */
- if (!state->m->parseddesc->params)
- descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags);
+ descriptor_params_from_paramtypes(state->m->parseddesc, state->m->flags);
/* pre-initialize variables as TYPE_VOID */
/* allocate parameters if necessary */
- if (!md->params)
- descriptor_params_from_paramtypes(
- md,
- (invokestatic) ? ACC_STATIC : ACC_NONE);
+ descriptor_params_from_paramtypes(
+ md,
+ (invokestatic) ? ACC_STATIC : ACC_NONE);
/* check parameter types */
/* allocate parameter descriptors if necessary */
- if (!state.m->parseddesc->params)
- descriptor_params_from_paramtypes(state.m->parseddesc,state.m->flags);
+ descriptor_params_from_paramtypes(state.m->parseddesc, state.m->flags);
/* allocate the stack buffers */
clonedesc->paramslots = 0;
clonedesc->paramtypes[0].classref = classrefs + 0;
clonedesc->params = NULL;
+ clonedesc->pool_lock = NULL;
/* create methodinfo */
/* is the descriptor fully parsed? */
- if (md->params == NULL)
- descriptor_params_from_paramtypes(md, m->flags);
+ descriptor_params_from_paramtypes(md, m->flags);
paramcount = md->paramcount;
/* is the descriptor fully parsed? */
- if (m->parseddesc->params == NULL)
- descriptor_params_from_paramtypes(md, m->flags);
+ descriptor_params_from_paramtypes(md, m->flags);
paramtypes = md->paramtypes;
paramcount = md->paramcount;
/* have the method params already been parsed? no, do it. */
- if (!mi->parseddesc->params)
- descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
+ descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
/* cache the result of the resolution */
/* have the method params already been parsed? no, do it. */
- if (!mi->parseddesc->params)
- descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
+ descriptor_params_from_paramtypes(mi->parseddesc, mi->flags);
/* cache the resolution */
#endif
/* allocate params if necessary */
- if (!methodref->parseddesc.md->params)
- descriptor_params_from_paramtypes(
- methodref->parseddesc.md,
- (invokestatic) ? ACC_STATIC : ACC_NONE);
+ descriptor_params_from_paramtypes(
+ methodref->parseddesc.md,
+ (invokestatic) ? ACC_STATIC : ACC_NONE);
/* create the data structure */
ref = NEW(unresolved_method);