struct vm_object *vm_string_intern(struct vm_object *string) { struct vm_reference *intern; struct vm_object *result; pthread_mutex_lock(&literals_mutex); if (hash_map_get(literals, string, (void **) &intern) == 0) { pthread_mutex_unlock(&literals_mutex); result = vm_reference_get(intern); return result; } result = string; intern = vm_reference_alloc(result, VM_REFERENCE_STRONG); if (!intern) { result = throw_oom_error(); goto out; } if (hash_map_put(literals, string, intern)) result = throw_oom_error(); out: pthread_mutex_unlock(&literals_mutex); return result; }
struct vm_object *vm_string_intern(struct vm_object *string) { struct vm_object *intern; pthread_rwlock_rdlock(&literals_rwlock); if (hash_map_get(literals, string, (void **) &intern) == 0) { pthread_rwlock_unlock(&literals_rwlock); return intern; } pthread_rwlock_unlock(&literals_rwlock); pthread_rwlock_wrlock(&literals_rwlock); /* * XXX: we should notify GC that we store a reference to * string here (both as a key and a value). It should be * marked as a weak reference. */ intern = string; if (hash_map_put(literals, string, intern)) intern = throw_oom_error(); pthread_rwlock_unlock(&literals_rwlock); return intern; }