PR163: descriptor_params_from_paramtypes is protected by a mutex now (per descriptor...
[cacao.git] / src / vm / descriptor.cpp
index ec71b8095a016024947f6fb49640db1cb2e80264..2748ac38d85931064e1c0ed4884dd2e05a1ed2af 100644 (file)
@@ -771,7 +771,11 @@ descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool)
 
        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;
        }
 
@@ -921,6 +925,7 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
        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 '(' */
@@ -1010,6 +1015,9 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
                                        md_param_alloc(md);
                        }
 #endif
+
+               /* params already initialized; no need to lock */
+               md->pool_lock = NULL;
        }
        else {
                /* params will be allocated later by
@@ -1027,35 +1035,37 @@ descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
 
 /* 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.
 
-   RETURN VALUE:
-       true.............the paramdescs were created successfully
-          false............an exception has been thrown
-
    POSTCONDITION:
        md->parms != NULL
 
 *******************************************************************************/
 
-bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
+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 */
 
@@ -1113,7 +1123,8 @@ bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
                }
 #endif
 
-       return true;
+       if (has_lock)
+               md->pool_lock->unlock();
 }