Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

make reinterpret() share data

add pointer_to_array() for wrapping a pointer as an array
fixes #232, #712
  • Loading branch information...
commit 42fc5ec6ecb30ca9fb7300c6d79b92d717ede947 1 parent d47926a
@JeffBezanson JeffBezanson authored
View
16 base/array.jl
@@ -35,10 +35,16 @@ end
copy_to{T}(dest::Array{T}, src::Array{T}) = copy_to(dest, 1, src, 1, numel(src))
-function reinterpret{T,S}(::Type{T}, a::Array{S})
- b = Array(T, div(numel(a)*sizeof(S),sizeof(T)))
- ccall(:memcpy, Ptr{T}, (Ptr{T}, Ptr{S}, Uint), b, a, length(b)*sizeof(T))
- return b
+function reinterpret{T,S}(::Type{T}, a::Array{S,1})
+ nel = int(div(numel(a)*sizeof(S),sizeof(T)))
+ ccall(:jl_reshape_array, Array{T,1}, (Any, Any, Any), Array{T,1}, a, (nel,))
+end
+function reinterpret{T,S,N}(::Type{T}, a::Array{S}, dims::NTuple{N,Int})
+ nel = div(numel(a)*sizeof(S),sizeof(T))
+ if prod(dims) != nel
+ error("reinterpret: invalid dimensions")
+ end
+ ccall(:jl_reshape_array, Array{T,N}, (Any, Any, Any), Array{T,N}, a, dims)
end
reinterpret(t,x) = reinterpret(t,[x])[1]
@@ -46,7 +52,7 @@ function reshape{T,N}(a::Array{T}, dims::NTuple{N,Int})
if prod(dims) != numel(a)
error("reshape: invalid dimensions")
end
- ccall(:jl_reshape_array, Any, (Any, Any, Any), Array{T,N}, a, dims)::Array{T,N}
+ ccall(:jl_reshape_array, Array{T,N}, (Any, Any, Any), Array{T,N}, a, dims)
end
## Constructors ##
View
8 base/pointer.jl
@@ -25,6 +25,14 @@ pointer{T}(::Type{T}, x::Uint) = convert(Ptr{T}, x)
pointer{T}(x::AbstractArray{T}) = convert(Ptr{T},x)
pointer{T}(x::AbstractArray{T}, i::Int) = convert(Ptr{T},x) + (i-1)*sizeof(T)
+# unsafe pointer to array conversions
+pointer_to_array(p, dims) = pointer_to_array(p, dims, false)
+function pointer_to_array{T,N}(p::Ptr{T}, dims::NTuple{N,Int},
+ julia_malloc::Bool)
+ ccall(:jl_ptr_to_array, Array{T,N}, (Any, Ptr, Any, Int32),
+ Array{T,N}, p, dims, julia_malloc)
+end
+
integer(x::Ptr) = convert(Uint, x)
unsigned(x::Ptr) = convert(Uint, x)
View
5 extras/iostring.jl
@@ -6,8 +6,9 @@ type IOString <: IO
ptr::Int
IOString(data::Vector{Uint8}) = new(data, 1)
+ # TODO: should be copy on write if given a string
IOString(str::String) = IOString(str.data)
- IOString() = IOString("")
+ IOString() = IOString(Uint8[])
end
function read{T}(from::IOString, a::Array{T})
@@ -56,4 +57,4 @@ function write(to::IOString, a::Uint8)
end
to.data[to.ptr] = a
to.ptr += 1
-end
+end
View
102 src/array.c
@@ -67,6 +67,7 @@ static jl_array_t *_new_array(jl_type_t *atype,
a->length = nel;
a->ndims = ndims;
a->reshaped = 0;
+ a->ptrarray = !isunboxed;
a->elsize = elsz;
if (ndims == 1) {
a->nrows = nel;
@@ -101,6 +102,7 @@ jl_array_t *jl_reshape_array(jl_type_t *atype, jl_array_t *data,
a->length = data->length;
a->elsize = data->elsize;
a->ndims = ndims;
+ a->ptrarray = data->ptrarray;
a->reshaped = 1;
if (ndims == 1) {
@@ -118,6 +120,102 @@ jl_array_t *jl_reshape_array(jl_type_t *atype, jl_array_t *data,
return a;
}
+// ** NOTE: julia_mallocated means buffer was allocated using julia_malloc.
+// using the address of another array does not work!!
+jl_array_t *jl_ptr_to_array_1d(jl_type_t *atype, void *data, size_t nel,
+ int julia_mallocated)
+{
+ size_t elsz;
+ jl_array_t *a;
+ jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);
+
+ int isunboxed = jl_is_bits_type(el_type);
+ if (isunboxed)
+ elsz = jl_bitstype_nbits(el_type)/8;
+ else
+ elsz = sizeof(void*);
+
+ a = allocobj(sizeof(jl_array_t));
+ a->type = atype;
+ a->data = data;
+ a->length = nel;
+ a->elsize = elsz;
+ a->ptrarray = !isunboxed;
+ a->ndims = 1;
+
+ if (julia_mallocated) {
+ a->reshaped = 0;
+ jl_gc_acquire_buffer(data);
+ }
+ else {
+ // this marks the array as not owning its buffer
+ a->reshaped = 1;
+ *((jl_array_t**)(&a->_space[0])) = a;
+ }
+
+ a->nrows = a->length;
+ a->maxsize = a->length;
+ a->offset = 0;
+
+ return a;
+}
+
+jl_array_t *jl_ptr_to_array(jl_type_t *atype, void *data, jl_tuple_t *dims,
+ int julia_mallocated)
+{
+ size_t i, elsz, nel=1;
+ jl_array_t *a;
+ size_t ndims = dims->length;
+
+ for(i=0; i < ndims; i++) {
+ nel *= jl_unbox_long(jl_tupleref(dims, i));
+ }
+ jl_type_t *el_type = (jl_type_t*)jl_tparam0(atype);
+
+ int isunboxed = jl_is_bits_type(el_type);
+ if (isunboxed)
+ elsz = jl_bitstype_nbits(el_type)/8;
+ else
+ elsz = sizeof(void*);
+
+ int ndimwords = (ndims > 2 ? (ndims-2) : 0);
+#ifndef __LP64__
+ // on 32-bit, ndimwords must be odd to preserve 8-byte alignment
+ ndimwords += (~ndimwords)&1;
+#endif
+ a = allocobj(sizeof(jl_array_t) + ndimwords*sizeof(size_t));
+ a->type = atype;
+ a->data = data;
+ a->length = nel;
+ a->elsize = elsz;
+ a->ptrarray = !isunboxed;
+ a->ndims = ndims;
+
+ if (julia_mallocated) {
+ a->reshaped = 0;
+ jl_gc_acquire_buffer(data);
+ }
+ else {
+ // this marks the array as not owning its buffer
+ a->reshaped = 1;
+ *((jl_array_t**)(&a->_space[0] + ndimwords*sizeof(size_t))) = a;
+ }
+
+ if (ndims == 1) {
+ a->nrows = a->length;
+ a->maxsize = a->length;
+ a->offset = 0;
+ }
+ else {
+ size_t *adims = &a->nrows;
+ for(i=0; i < ndims; i++) {
+ adims[i] = jl_unbox_long(jl_tupleref(dims, i));
+ }
+ }
+
+ return a;
+}
+
jl_array_t *jl_new_array_(jl_type_t *atype, uint32_t ndims, size_t *dims)
{
return _new_array(atype, ndims, dims);
@@ -335,11 +433,11 @@ static void *array_new_buffer(jl_array_t *a, size_t newlen)
if (a->elsize == 1) {
nbytes++;
}
- int isunboxed = jl_is_bits_type(jl_tparam0(jl_typeof(a)));
char *newdata = allocb(nbytes);
- if (!isunboxed)
+ if (a->ptrarray)
memset(newdata, 0, nbytes);
if (a->elsize == 1) newdata[nbytes-1] = '\0';
+ a->reshaped = 0;
return newdata;
}
View
2  src/gc.c
@@ -485,7 +485,7 @@ static void gc_markval_(jl_value_t *v)
gc_setmark(data);
}
}
- if (gc_typeof(jl_tparam0(vt)) != (jl_value_t*)jl_bits_kind) {
+ if (a->ptrarray) {
size_t l = a->length;
if (l > 0) {
for(size_t i=0; i < l-1; i++) {
View
2  src/julia.expmap
@@ -21,6 +21,8 @@
jl_new_closure;
jl_new_array;
jl_reshape_array;
+ jl_ptr_to_array_1d;
+ jl_ptr_to_array;
jl_alloc_array_1d;
jl_alloc_array_2d;
jl_alloc_array_3d;
View
8 src/julia.h
@@ -47,8 +47,9 @@ typedef struct {
JL_STRUCT_TYPE
void *data;
size_t length;
- unsigned short ndims:15;
+ unsigned short ndims:14;
unsigned short reshaped:1;
+ unsigned short ptrarray:1; // representation is pointer array
uint16_t elsize;
uint32_t offset; // for 1-d only. does not need to get big.
size_t nrows;
@@ -606,6 +607,11 @@ DLLEXPORT jl_array_t *jl_new_arrayv(jl_type_t *atype, ...);
jl_array_t *jl_new_array_(jl_type_t *atype, uint32_t ndims, size_t *dims);
DLLEXPORT jl_array_t *jl_reshape_array(jl_type_t *atype, jl_array_t *data,
jl_tuple_t *dims);
+DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_type_t *atype, void *data,
+ size_t nel, int julia_mallocated);
+DLLEXPORT jl_array_t *jl_ptr_to_array(jl_type_t *atype, void *data,
+ jl_tuple_t *dims, int julia_mallocated);
+
DLLEXPORT jl_array_t *jl_alloc_array_1d(jl_type_t *atype, size_t nr);
DLLEXPORT jl_array_t *jl_alloc_array_2d(jl_type_t *atype, size_t nr, size_t nc);
DLLEXPORT jl_array_t *jl_alloc_array_3d(jl_type_t *atype, size_t nr, size_t nc,
View
6 src/sys.c
@@ -146,11 +146,7 @@ jl_array_t *jl_takebuf_array(ios_t *s)
else {
assert(s->julia_alloc);
char *b = ios_takebuf(s, &n);
- a = jl_alloc_array_1d(jl_array_uint8_type, 0);
- a->data = b;
- a->length = n-1;
- a->nrows = n-1;
- jl_gc_acquire_buffer(b);
+ a = jl_ptr_to_array_1d(jl_array_uint8_type, b, n-1, 1);
}
return a;
}

0 comments on commit 42fc5ec

Please sign in to comment.
Something went wrong with that request. Please try again.