Skip to content

Commit

Permalink
second pass at 'precious_{preserve,remove}'
Browse files Browse the repository at this point in the history
  • Loading branch information
Enchufa2 authored and eddelbuettel committed Jan 18, 2021
1 parent 519909c commit 21ddbb9
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 121 deletions.
215 changes: 170 additions & 45 deletions inst/include/Rcpp/String.h

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions inst/include/Rcpp/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@ inline void resumeJump(SEXP token) {
if (isLongjumpSentinel(token)) {
token = getLongjumpToken(token);
}
//::R_ReleaseObject(token);
Rcpp_precious_remove(token);
::R_ReleaseObject(token);
#if (defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0))
::R_ContinueUnwind(token);
#endif // #nocov end
Expand Down
20 changes: 10 additions & 10 deletions inst/include/Rcpp/routines.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ namespace Rcpp{

void Rcpp_precious_init();
void Rcpp_precious_teardown();
void Rcpp_precious_preserve(SEXP object);
void Rcpp_precious_remove(SEXP object);
SEXP Rcpp_precious_preserve(SEXP object);
void Rcpp_precious_remove(SEXP token);
}

SEXP rcpp_get_stack_trace();
Expand Down Expand Up @@ -133,24 +133,24 @@ namespace Rcpp {
}

inline attribute_hidden void Rcpp_precious_init() {
typedef int (*Fun)(void);
typedef void (*Fun)(void);
static Fun fun = GET_CALLABLE("Rcpp_precious_init");
fun();
}
inline attribute_hidden void Rcpp_precious_teardown() {
typedef int (*Fun)(void);
typedef void (*Fun)(void);
static Fun fun = GET_CALLABLE("Rcpp_precious_teardown");
fun();
}
inline attribute_hidden void Rcpp_precious_preserve(SEXP object) {
typedef const char* (*Fun)(SEXP);
inline attribute_hidden SEXP Rcpp_precious_preserve(SEXP object) {
typedef SEXP (*Fun)(SEXP);
static Fun fun = GET_CALLABLE("Rcpp_precious_preserve");
fun(object);
return fun(object);
}
inline attribute_hidden void Rcpp_precious_remove(SEXP object) {
typedef const char* (*Fun)(SEXP);
inline attribute_hidden void Rcpp_precious_remove(SEXP token) {
typedef void (*Fun)(SEXP);
static Fun fun = GET_CALLABLE("Rcpp_precious_remove");
fun(object);
fun(token);
}

}
Expand Down
14 changes: 11 additions & 3 deletions inst/include/Rcpp/storage/PreserveStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ namespace Rcpp{
class PreserveStorage {
public:

PreserveStorage() : data(R_NilValue){}
PreserveStorage() : data(R_NilValue), token(R_NilValue){}

~PreserveStorage(){
Rcpp_ReleaseObject(data) ;
Rcpp_ReleaseObject(token) ;
data = R_NilValue;
token = R_NilValue;
}

inline void set__(SEXP x){
data = Rcpp_ReplaceObject(data, x) ;
if (data != x) {
data = x;
Rcpp_ReleaseObject(token);
token = Rcpp_PreserveObject(data);
}

// calls the update method of CLASS
// this is where to react to changes in the underlying SEXP
Expand All @@ -28,7 +33,9 @@ namespace Rcpp{

inline SEXP invalidate__(){
SEXP out = data ;
Rcpp_ReleaseObject(token);
data = R_NilValue ;
token = R_NilValue ;
return out ;
}

Expand All @@ -48,6 +55,7 @@ namespace Rcpp{

private:
SEXP data ;
SEXP token ;
} ;

}
Expand Down
15 changes: 7 additions & 8 deletions inst/include/Rcpp/traits/named_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,22 @@ template <typename T> class named_object {
template <> class named_object<SEXP> {
public: // #nocov start
named_object( const std::string& name_, const SEXP& o_):
name(name_), object(o_) {
//R_PreserveObject(object);
Rcpp_precious_preserve(object);
name(name_), object(o_), token(R_NilValue) {
token = Rcpp_precious_preserve(object);
}

named_object( const named_object<SEXP>& other ) :
name(other.name), object(other.object) {
//R_PreserveObject(object);
Rcpp_precious_preserve(object);
name(other.name), object(other.object), token(other.token) {
token = Rcpp_precious_preserve(object);
}
~named_object() {
//R_ReleaseObject(object);
Rcpp_precious_remove(object);
Rcpp_precious_remove(token);

} // #nocov end
const std::string& name;
SEXP object;
private:
SEXP token;
};


Expand Down
3 changes: 1 addition & 2 deletions inst/include/Rcpp/unwindProtect.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ inline SEXP unwindProtect(SEXP (*callback)(void* data), void* data) {
// in C++ destructors. Can't use PROTECT() for this because
// UNPROTECT() might be called in a destructor, for instance if a
// Shield<SEXP> is on the stack.
//::R_PreserveObject(token);
Rcpp::Rcpp_precious_preserve(token);
::R_PreserveObject(token);

throw LongjumpException(token);
}
Expand Down
33 changes: 5 additions & 28 deletions inst/include/RcppCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ namespace Rcpp {
SEXP Rcpp_fast_eval(SEXP expr_, SEXP env);
SEXP Rcpp_eval(SEXP expr_, SEXP env = R_GlobalEnv);

void Rcpp_precious_preserve(SEXP object);
void Rcpp_precious_remove(SEXP object);
SEXP Rcpp_precious_preserve(SEXP object);
void Rcpp_precious_remove(SEXP token);

namespace internal {
SEXP Rcpp_eval_impl(SEXP expr, SEXP env);
Expand All @@ -90,35 +90,12 @@ namespace Rcpp {
template <typename T> class named_object;
}

// inline SEXP Rcpp_PreserveObject(SEXP x) {
// if (x != R_NilValue) {
// R_PreserveObject(x);
// }
// return x;
// }
inline SEXP Rcpp_PreserveObject(SEXP object) {
Rcpp_precious_preserve(object);
return object;
return Rcpp_precious_preserve(object);
}

// inline void Rcpp_ReleaseObject(SEXP x) {
// if (x != R_NilValue) {
// R_ReleaseObject(x);
// }
// }
inline void Rcpp_ReleaseObject(SEXP object) {
Rcpp_precious_remove(object);
}

inline SEXP Rcpp_ReplaceObject(SEXP x, SEXP y) {

// if we are setting to the same SEXP as we already have, do nothing
if (x != y) {
Rcpp_ReleaseObject(x);
Rcpp_PreserveObject(y);
}

return y;
inline void Rcpp_ReleaseObject(SEXP token) {
Rcpp_precious_remove(token);
}

}
Expand Down
50 changes: 27 additions & 23 deletions src/barrier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,35 +90,39 @@ namespace Rcpp {
static SEXP Rcpp_precious = R_NilValue;
// [[Rcpp::register]]
void Rcpp_precious_init() {
Rcpp_precious = CONS(R_NilValue,R_NilValue);// set up
R_PreserveObject(Rcpp_precious); // and protect
Rcpp_precious = CONS(R_NilValue, R_NilValue); // set up
R_PreserveObject(Rcpp_precious); // and protect
}
// [[Rcpp::register]]
void Rcpp_precious_teardown() {
R_ReleaseObject(Rcpp_precious); // release resource
}
// [[Rcpp::register]]
void Rcpp_precious_preserve(SEXP object) {
SETCDR(Rcpp_precious, CONS(object, CDR(Rcpp_precious)));
}
SEXP DeleteFromList(SEXP object, SEXP list) {
if (CAR(list) == object)
return CDR(list);
else {
SEXP last = list;
for (SEXP head = CDR(list); head != R_NilValue; head = CDR(head)) {
if (CAR(head) == object) {
SETCDR(last, CDR(head));
return list;
}
else last = head;
}
return list;
R_ReleaseObject(Rcpp_precious); // release resource
}
// [[Rcpp::register]]
SEXP Rcpp_precious_preserve(SEXP object) {
if (object == R_NilValue) {
return R_NilValue;
}
PROTECT(object);
SEXP cell = PROTECT(CONS(Rcpp_precious, CDR(Rcpp_precious)));
SET_TAG(cell, object);
SETCDR(Rcpp_precious, cell);
if (CDR(cell) != R_NilValue) {
SETCAR(CDR(cell), cell);
}
UNPROTECT(2);
return cell;
}
// [[Rcpp::register]]
void Rcpp_precious_remove(SEXP object) {
SETCDR(Rcpp_precious, DeleteFromList(object, CDR(Rcpp_precious)));
void Rcpp_precious_remove(SEXP token) {
if (token == R_NilValue) {
return;
}
SEXP before = CAR(token);
SEXP after = CDR(token);
SETCDR(before, after);
if (after != R_NilValue) {
SETCAR(after, before);
}
}
}

Expand Down

0 comments on commit 21ddbb9

Please sign in to comment.