Skip to content
Snippets Groups Projects
Commit d333182f authored by Florian Angerer's avatar Florian Angerer
Browse files

Implemented simple cache to avoid upcalls in functions 'INTEGER' and 'REAL'.

parent 2cd617bc
No related branches found
No related tags found
No related merge requests found
...@@ -1011,37 +1011,37 @@ int SETLEVELS(SEXP x, int v) { ...@@ -1011,37 +1011,37 @@ int SETLEVELS(SEXP x, int v) {
return 0; return 0;
} }
int *INTEGER(SEXP x) { int *FASTR_INTEGER(SEXP x) {
TRACE0(); TRACE(TARGp, x);
SEXP result = ((call_INTEGER) callbacks[INTEGER_x])(x); int *result = ((call_INTEGER) callbacks[INTEGER_x])(x);
checkExitCall(); checkExitCall();
return result; return result;
} }
int *LOGICAL(SEXP x){ int *LOGICAL(SEXP x){
TRACE0(); TRACE0();
SEXP result = ((call_LOGICAL) callbacks[LOGICAL_x])(x); int *result = ((call_LOGICAL) callbacks[LOGICAL_x])(x);
checkExitCall(); checkExitCall();
return result; return result;
} }
double *REAL(SEXP x){ double *FASTR_REAL(SEXP x){
TRACE0(); TRACE(TARGp, x);
SEXP result = ((call_REAL) callbacks[REAL_x])(x); double *result = ((call_REAL) callbacks[REAL_x])(x);
checkExitCall(); checkExitCall();
return result; return result;
} }
Rbyte *RAW(SEXP x) { Rbyte *RAW(SEXP x) {
TRACE0(); TRACE0();
SEXP result = ((call_RAW) callbacks[RAW_x])(x); Rbyte *result = ((call_RAW) callbacks[RAW_x])(x);
checkExitCall(); checkExitCall();
return result; return result;
} }
Rcomplex *COMPLEX(SEXP x) { Rcomplex *COMPLEX(SEXP x) {
TRACE0(); TRACE0();
SEXP result = ((call_COMPLEX) callbacks[COMPLEX_x])(x); Rcomplex *result = ((call_COMPLEX) callbacks[COMPLEX_x])(x);
checkExitCall(); checkExitCall();
return result; return result;
} }
......
...@@ -98,4 +98,11 @@ const char *R_CHAR(SEXP charsxp) { ...@@ -98,4 +98,11 @@ const char *R_CHAR(SEXP charsxp) {
return ((call_charSXPToNativeCharArray) callbacks[charSXPToNativeCharArray_x])(charsxp); return ((call_charSXPToNativeCharArray) callbacks[charSXPToNativeCharArray_x])(charsxp);
} }
int *INTEGER(SEXP x) {
return FASTR_INTEGER(x);
}
double *REAL(SEXP x){
return FASTR_REAL(x);
}
...@@ -36,10 +36,6 @@ void*** Rinternals_getCallbacksAddress() { ...@@ -36,10 +36,6 @@ void*** Rinternals_getCallbacksAddress() {
return &callbacks; return &callbacks;
} }
static int* return_int;
static double* return_double;
static char* return_byte;
char *ensure_truffle_chararray_n(const char *x, int n) { char *ensure_truffle_chararray_n(const char *x, int n) {
return (char *) x; return (char *) x;
} }
...@@ -49,3 +45,77 @@ void *ensure_string(const char * x) { ...@@ -49,3 +45,77 @@ void *ensure_string(const char * x) {
} }
#include "../truffle_common/Rinternals_truffle_common.h" #include "../truffle_common/Rinternals_truffle_common.h"
#define ARRAY_CACHE_SIZE 5
typedef struct array_cache_entry {
SEXP key;
void *data;
unsigned int hits;
} ArrayCacheEntry;
static __thread ArrayCacheEntry int_cache[ARRAY_CACHE_SIZE];
static __thread ArrayCacheEntry real_cache[ARRAY_CACHE_SIZE];
static inline int array_cache_lookup(ArrayCacheEntry *cache, SEXP key) {
#if ARRAY_CACHE_SIZE > 0
for(int i=0; i < ARRAY_CACHE_SIZE; i++) {
if(cache[i].key == key) {
(cache[i].hits)++;
return i;
}
}
#endif
return -1;
}
static inline void array_cache_insert(ArrayCacheEntry *cache, SEXP key,
void *data) {
#if ARRAY_CACHE_SIZE > 0
// replace least frequent
unsigned hits = cache[0].hits;
int idx = 0;
for (int i = 1; i < ARRAY_CACHE_SIZE && hits != 0; i++) {
if (cache[i].hits < hits) {
hits = cache[i].hits;
idx = i;
}
}
cache[idx].key = key;
cache[idx].data = data;
cache[idx].hits = 0;
#endif
}
int *INTEGER(SEXP x) {
TRACE(TARGp, x);
// lookup in cache
int idx = array_cache_lookup(int_cache, x);
if(idx >= 0) {
return (int *)int_cache[idx].data;
}
int *result = FASTR_INTEGER(x);
array_cache_insert(int_cache, x, result);
return result;
}
double *REAL(SEXP x){
TRACE(TARGp, x);
// lookup in cache
int idx = array_cache_lookup(real_cache, x);
if(idx >= 0) {
return (double *)real_cache[idx].data;
}
double *result = FASTR_REAL(x);
array_cache_insert(real_cache, x, result);
return result;
}
42 43
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment