Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,6 @@ macro ccall(exprs...)
return ccall_macro_lower((:ccall), ccall_macro_parse(exprs)...)
end

macro ccall_effects(effects::UInt16, expr)
return ccall_macro_lower((:ccall, effects), ccall_macro_parse(expr)...)
macro ccall_effects(effects::UInt16, exprs...)
return ccall_macro_lower((:ccall, effects), ccall_macro_parse(exprs)...)
end

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6e3a44c3870f135953b325a155fecd65
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
565bdb1a4e8bda374d08a49b2ba70130762ca06004cc50d07ca58ca9a3741195977f563bc990bd627735b6464162a15a7bfb08570e812abf2f22151713de2210
7 changes: 3 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2838,10 +2838,9 @@ static void visitLine(jl_codectx_t &ctx, uint64_t *ptr, Value *addend, const cha
Value *pv = ConstantExpr::getIntToPtr(
ConstantInt::get(ctx.types().T_size, (uintptr_t)ptr),
getPointerTy(ctx.builder.getContext()));
Value *v = ctx.builder.CreateLoad(getInt64Ty(ctx.builder.getContext()), pv, true, name);
v = ctx.builder.CreateAdd(v, addend);
ctx.builder.CreateStore(v, pv, true); // volatile, not atomic, so this might be an underestimate,
// but it's faster this way
ctx.builder.CreateAtomicRMW(AtomicRMWInst::Add, pv,
addend, MaybeAlign(),
AtomicOrdering::Monotonic);
}

// Code coverage
Expand Down
52 changes: 37 additions & 15 deletions src/coverage.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// This file is a part of Julia. License is MIT: https://julialang.org/license

#include <cstdint>
#include <pthread.h>
#include <string>
#include <fstream>
#include <map>
Expand All @@ -15,7 +17,7 @@

using namespace llvm;

static int codegen_imaging_mode(void)
static int codegen_imaging_mode(void) JL_NOTSAFEPOINT
{
return jl_options.image_codegen || (jl_generating_output() && jl_options.use_pkgimages);
}
Expand All @@ -26,7 +28,9 @@ const int logdata_blocksize = 32; // target getting nearby lines in the same gen
typedef uint64_t logdata_block[logdata_blocksize];
typedef StringMap< SmallVector<logdata_block*, 0> > logdata_t;

static uint64_t *allocLine(SmallVector<logdata_block*, 0> &vec, int line)
pthread_mutex_t coverage_lock = PTHREAD_MUTEX_INITIALIZER;

static uint64_t *allocLine(SmallVector<logdata_block*, 0> &vec, int line) JL_NOTSAFEPOINT
{
unsigned block = line / logdata_blocksize;
line = line % logdata_blocksize;
Expand All @@ -45,39 +49,49 @@ static uint64_t *allocLine(SmallVector<logdata_block*, 0> &vec, int line)

static logdata_t coverageData;

JL_DLLEXPORT void jl_coverage_alloc_line(StringRef filename, int line)
JL_DLLEXPORT void jl_coverage_alloc_line(StringRef filename, int line) JL_NOTSAFEPOINT
{
assert(!codegen_imaging_mode());
if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
return;
pthread_mutex_lock(&coverage_lock);
allocLine(coverageData[filename], line);
pthread_mutex_unlock(&coverage_lock);
}

JL_DLLEXPORT uint64_t *jl_coverage_data_pointer(StringRef filename, int line)
JL_DLLEXPORT uint64_t *jl_coverage_data_pointer(StringRef filename, int line) JL_NOTSAFEPOINT
{
return allocLine(coverageData[filename], line);
pthread_mutex_lock(&coverage_lock);
uint64_t* ret = allocLine(coverageData[filename], line);
pthread_mutex_unlock(&coverage_lock);
return ret;
}

extern "C" JL_DLLEXPORT void jl_coverage_visit_line(const char *filename_, size_t len_filename, int line)
extern "C" JL_DLLEXPORT void jl_coverage_visit_line(const char *filename_, size_t len_filename, int line) JL_NOTSAFEPOINT
{
StringRef filename = StringRef(filename_, len_filename);
if (codegen_imaging_mode() || filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
return;
pthread_mutex_lock(&coverage_lock);
SmallVector<logdata_block*, 0> &vec = coverageData[filename];
uint64_t *ptr = allocLine(vec, line);
(*ptr)++;
pthread_mutex_unlock(&coverage_lock);
}

// Memory allocation log (malloc_log)

static logdata_t mallocData;

JL_DLLEXPORT uint64_t *jl_malloc_data_pointer(StringRef filename, int line)
JL_DLLEXPORT uint64_t *jl_malloc_data_pointer(StringRef filename, int line) JL_NOTSAFEPOINT
{
return allocLine(mallocData[filename], line);
pthread_mutex_lock(&coverage_lock);
uint64_t* ret = allocLine(mallocData[filename], line);
pthread_mutex_unlock(&coverage_lock);
return ret;
}

static void clear_log_data(logdata_t &logData, int resetValue)
static void clear_log_data(logdata_t &logData, int resetValue) JL_NOTSAFEPOINT
{
logdata_t::iterator it = logData.begin();
for (; it != logData.end(); it++) {
Expand All @@ -97,18 +111,22 @@ static void clear_log_data(logdata_t &logData, int resetValue)
}

// Resets the malloc counts.
extern "C" JL_DLLEXPORT void jl_clear_malloc_data(void)
extern "C" JL_DLLEXPORT void jl_clear_malloc_data(void) JL_NOTSAFEPOINT
{
pthread_mutex_lock(&coverage_lock);
clear_log_data(mallocData, 1);
pthread_mutex_unlock(&coverage_lock);
}

// Resets the code coverage
extern "C" JL_DLLEXPORT void jl_clear_coverage_data(void)
extern "C" JL_DLLEXPORT void jl_clear_coverage_data(void) JL_NOTSAFEPOINT
{
pthread_mutex_lock(&coverage_lock);
clear_log_data(coverageData, 0);
pthread_mutex_unlock(&coverage_lock);
}

static void write_log_data(logdata_t &logData, const char *extension)
static void write_log_data(logdata_t &logData, const char *extension) JL_NOTSAFEPOINT
{
std::string base = std::string(jl_options.julia_bindir);
base = base + "/../share/julia/base/";
Expand Down Expand Up @@ -163,7 +181,7 @@ static void write_log_data(logdata_t &logData, const char *extension)
}
}

static void write_lcov_data(logdata_t &logData, const std::string &outfile)
static void write_lcov_data(logdata_t &logData, const std::string &outfile) JL_NOTSAFEPOINT
{
std::ofstream outf(outfile.c_str(), std::ofstream::ate | std::ofstream::out | std::ofstream::binary);
//std::string base = std::string(jl_options.julia_bindir);
Expand Down Expand Up @@ -203,8 +221,9 @@ static void write_lcov_data(logdata_t &logData, const std::string &outfile)
outf.close();
}

extern "C" JL_DLLEXPORT void jl_write_coverage_data(const char *output)
extern "C" JL_DLLEXPORT void jl_write_coverage_data(const char *output) JL_NOTSAFEPOINT
{
pthread_mutex_lock(&coverage_lock);
if (output) {
StringRef output_pattern(output);
if (output_pattern.ends_with(".info"))
Expand All @@ -215,11 +234,14 @@ extern "C" JL_DLLEXPORT void jl_write_coverage_data(const char *output)
raw_string_ostream(stm) << "." << uv_os_getpid() << ".cov";
write_log_data(coverageData, stm.c_str());
}
pthread_mutex_unlock(&coverage_lock);
}

extern "C" void jl_write_malloc_log(void)
extern "C" void jl_write_malloc_log(void) JL_NOTSAFEPOINT
{
pthread_mutex_lock(&coverage_lock);
std::string stm;
raw_string_ostream(stm) << "." << uv_os_getpid() << ".mem";
write_log_data(mallocData, stm.c_str());
pthread_mutex_unlock(&coverage_lock);
}
7 changes: 4 additions & 3 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static int8_t jl_cachearg_offset(void)
/// ----- Insertion logic for special entries ----- ///


static uint_t speccache_hash(size_t idx, jl_value_t *data)
uint_t speccache_hash(size_t idx, jl_value_t *data)
{
jl_method_instance_t *ml = (jl_method_instance_t*)jl_svecref(data, idx); // This must always happen inside the lock
jl_value_t *sig = ml->specTypes;
Expand All @@ -150,7 +150,7 @@ static int speccache_eq(size_t idx, const void *ty, jl_value_t *data, uint_t hv)
// get or create the MethodInstance for a specialization
static jl_method_instance_t *jl_specializations_get_linfo_(jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams, jl_method_instance_t *mi_insert)
{
if (m->sig == (jl_value_t*)jl_anytuple_type && jl_atomic_load_relaxed(&m->unspecialized) != NULL && m != jl_opaque_closure_method && !m->is_for_opaque_closure)
if (m->source == NULL && m->generator == NULL && jl_atomic_load_relaxed(&m->unspecialized) != NULL && m != jl_opaque_closure_method && !m->is_for_opaque_closure)
return jl_atomic_load_relaxed(&m->unspecialized); // handle builtin methods
jl_value_t *ut = jl_is_unionall(type) ? jl_unwrap_unionall(type) : type;
JL_TYPECHK(specializations, datatype, ut);
Expand Down Expand Up @@ -3980,7 +3980,8 @@ STATIC_INLINE jl_value_t *_jl_invoke(jl_value_t *F, jl_value_t **args, uint32_t
// manually inlined copy of jl_method_compiled
jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mfunc->cache);
while (codeinst) {
if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) {
if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)
&& codeinst->owner == jl_nothing) {
jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke);
if (invoke != NULL) {
jl_value_t *res = invoke(F, args, nargs, codeinst);
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -2620,7 +2620,7 @@ JL_DLLEXPORT ssize_t jl_sizeof_jl_options(void);
// Parse an argc/argv pair to extract general julia options, passing back out
// any arguments that should be passed on to the script.
JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp);
JL_DLLEXPORT char *jl_format_filename(const char *output_pattern);
JL_DLLEXPORT char *jl_format_filename(const char *output_pattern) JL_NOTSAFEPOINT;

uint64_t parse_heap_size_hint(const char *optarg, const char *option_name);

Expand Down
4 changes: 2 additions & 2 deletions src/runtime_ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jl_value_t *jl_get_JIT(void)
// %L The local hostname.
// %l The local hostname, including the domain name.
// %u The local username.
std::string jl_format_filename(StringRef output_pattern)
std::string jl_format_filename(StringRef output_pattern) JL_NOTSAFEPOINT
{
std::string buf;
raw_string_ostream outfile(buf);
Expand Down Expand Up @@ -168,7 +168,7 @@ std::string jl_format_filename(StringRef output_pattern)
return outfile.str();
}

extern "C" JL_DLLEXPORT char *jl_format_filename(const char *output_pattern)
extern "C" JL_DLLEXPORT char *jl_format_filename(const char *output_pattern) JL_NOTSAFEPOINT
{
return strdup(jl_format_filename(StringRef(output_pattern)).c_str());
}
Expand Down
112 changes: 55 additions & 57 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -2624,49 +2624,64 @@ static void jl_prune_binding_backedges(jl_array_t *backedges)
jl_array_del_end(backedges, n - ins);
}


uint_t bindingkey_hash(size_t idx, jl_value_t *data);
uint_t speccache_hash(size_t idx, jl_value_t *data);

static void jl_prune_module_bindings(jl_module_t * m) JL_GC_DISABLED
static void jl_prune_idset(_Atomic(jl_svec_t*) *pkeys, _Atomic(jl_genericmemory_t*) *pkeyset, uint_t (*key_hash)(size_t, jl_value_t*), jl_value_t *parent) JL_GC_DISABLED
{
jl_svec_t *bindings = jl_atomic_load_relaxed(&m->bindings);
size_t l = jl_svec_len(bindings), i;
arraylist_t bindings_list;
arraylist_new(&bindings_list, 0);
jl_svec_t *keys = jl_atomic_load_relaxed(pkeys);
size_t l = jl_svec_len(keys), i;
if (l == 0)
return;
arraylist_t keys_list;
arraylist_new(&keys_list, 0);
for (i = 0; i < l; i++) {
jl_value_t *ti = jl_svecref(bindings, i);
if (ti == jl_nothing)
jl_value_t *k = jl_svecref(keys, i);
if (k == jl_nothing)
continue;
jl_binding_t *ref = ((jl_binding_t*)ti);
if (ptrhash_get(&serialization_order, ref) != HT_NOTFOUND)
arraylist_push(&bindings_list, ref);
}
jl_genericmemory_t *bindingkeyset = jl_atomic_load_relaxed(&m->bindingkeyset);
_Atomic(jl_genericmemory_t*)bindingkeyset2;
jl_atomic_store_relaxed(&bindingkeyset2, (jl_genericmemory_t*)jl_an_empty_memory_any);
jl_svec_t *bindings2 = jl_alloc_svec_uninit(bindings_list.len);
for (i = 0; i < bindings_list.len; i++) {
jl_binding_t *ref = (jl_binding_t*)bindings_list.items[i];
jl_svecset(bindings2, i, ref);
jl_smallintset_insert(&bindingkeyset2, (jl_value_t*)m, bindingkey_hash, i, (jl_value_t*)bindings2);
}
void *idx = ptrhash_get(&serialization_order, bindings);
if (ptrhash_get(&serialization_order, k) != HT_NOTFOUND)
arraylist_push(&keys_list, k);
}
jl_genericmemory_t *keyset = jl_atomic_load_relaxed(pkeyset);
_Atomic(jl_genericmemory_t*)keyset2;
jl_atomic_store_relaxed(&keyset2, (jl_genericmemory_t*)jl_an_empty_memory_any);
jl_svec_t *keys2 = jl_alloc_svec_uninit(keys_list.len);
for (i = 0; i < keys_list.len; i++) {
jl_binding_t *ref = (jl_binding_t*)keys_list.items[i];
jl_svecset(keys2, i, ref);
jl_smallintset_insert(&keyset2, parent, key_hash, i, (jl_value_t*)keys2);
}
void *idx = ptrhash_get(&serialization_order, keys);
assert(idx != HT_NOTFOUND && idx != (void*)(uintptr_t)-1);
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == bindings);
ptrhash_put(&serialization_order, bindings2, idx);
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = bindings2;
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == keys);
ptrhash_put(&serialization_order, keys2, idx);
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = keys2;

idx = ptrhash_get(&serialization_order, bindingkeyset);
idx = ptrhash_get(&serialization_order, keyset);
assert(idx != HT_NOTFOUND && idx != (void*)(uintptr_t)-1);
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == bindingkeyset);
ptrhash_put(&serialization_order, jl_atomic_load_relaxed(&bindingkeyset2), idx);
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = jl_atomic_load_relaxed(&bindingkeyset2);
jl_atomic_store_relaxed(&m->bindings, bindings2);
jl_atomic_store_relaxed(&m->bindingkeyset, jl_atomic_load_relaxed(&bindingkeyset2));
jl_gc_wb(m, bindings2);
jl_gc_wb(m, jl_atomic_load_relaxed(&bindingkeyset2));
assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == keyset);
ptrhash_put(&serialization_order, jl_atomic_load_relaxed(&keyset2), idx);
serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = jl_atomic_load_relaxed(&keyset2);
jl_atomic_store_relaxed(pkeys, keys2);
jl_gc_wb(parent, keys2);
jl_atomic_store_relaxed(pkeyset, jl_atomic_load_relaxed(&keyset2));
jl_gc_wb(parent, jl_atomic_load_relaxed(&keyset2));
}

static void jl_prune_method_specializations(jl_method_t *m) JL_GC_DISABLED
{
jl_value_t *specializations_ = jl_atomic_load_relaxed(&m->specializations);
if (!jl_is_svec(specializations_)) {
if (ptrhash_get(&serialization_order, specializations_) == HT_NOTFOUND)
record_field_change((jl_value_t **)&m->specializations, (jl_value_t*)jl_emptysvec);
return;
}
jl_prune_idset((_Atomic(jl_svec_t*)*)&m->specializations, &m->speckeyset, speccache_hash, (jl_value_t*)m);
}

static void jl_prune_module_bindings(jl_module_t *m) JL_GC_DISABLED
{
jl_prune_idset(&m->bindings, &m->bindingkeyset, bindingkey_hash, (jl_value_t*)m);
}

static void strip_slotnames(jl_array_t *slotnames, int n)
Expand Down Expand Up @@ -3231,32 +3246,15 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
// step 1.5: prune (garbage collect) some special weak references known caches
for (i = 0; i < serialization_queue.len; i++) {
jl_value_t *v = (jl_value_t*)serialization_queue.items[i];
if (jl_options.trim) {
if (jl_is_method(v)) {
jl_method_t *m = (jl_method_t*)v;
jl_value_t *specializations_ = jl_atomic_load_relaxed(&m->specializations);
if (!jl_is_svec(specializations_)) {
if (ptrhash_get(&serialization_order, specializations_) == HT_NOTFOUND)
record_field_change((jl_value_t **)&m->specializations, (jl_value_t*)jl_emptysvec);
continue;
}

jl_svec_t *specializations = (jl_svec_t *)specializations_;
size_t l = jl_svec_len(specializations), i;
for (i = 0; i < l; i++) {
jl_value_t *mi = jl_svecref(specializations, i);
if (mi == jl_nothing)
continue;
if (ptrhash_get(&serialization_order, mi) == HT_NOTFOUND)
jl_svecset(specializations, i, jl_nothing);
}
}
else if (jl_is_module(v)) {
if (jl_is_method(v)) {
if (jl_options.trim)
jl_prune_method_specializations((jl_method_t*)v);
}
else if (jl_is_module(v)) {
if (jl_options.trim)
jl_prune_module_bindings((jl_module_t*)v);
}
}
// Not else
if (jl_is_typename(v)) {
else if (jl_is_typename(v)) {
jl_typename_t *tn = (jl_typename_t*)v;
jl_atomic_store_relaxed(&tn->cache,
jl_prune_type_cache_hash(jl_atomic_load_relaxed(&tn->cache)));
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Pkg.version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PKG_BRANCH = release-1.12
PKG_SHA1 = 474c628764d6562453709bff686f7fc65dd23535
PKG_SHA1 = 69926e385c878253d62e2588a19b252277196ebf
PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git
PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1
2 changes: 1 addition & 1 deletion stdlib/REPL/src/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ find_hist_file() = get(ENV, "JULIA_HISTORY",
!isempty(DEPOT_PATH) ? joinpath(DEPOT_PATH[1], "logs", "repl_history.jl") :
error("DEPOT_PATH is empty and ENV[\"JULIA_HISTORY\"] not set."))

backend(r::AbstractREPL) = hasproperty(r, :backendref) ? r.backendref : nothing
backend(r::AbstractREPL) = hasproperty(r, :backendref) && isdefined(r, :backendref) ? r.backendref : nothing


function eval_on_backend(ast, backend::REPLBackendRef)
Expand Down
Loading