Skip to content

Commit

Permalink
src,deps: add ABI safe use of CheckMemoryPressure
Browse files Browse the repository at this point in the history
CheckMemoryPressure cannot be used ABI-safely from v8.h. Add a alternate
implementation of AdjustAmountOfExternalAllocatedMemory and then use
that from Node.
  • Loading branch information
ofrobots committed Nov 20, 2018
1 parent 0cad314 commit dc1bd96
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 17 deletions.
2 changes: 1 addition & 1 deletion deps/v8/include/v8-version.h
Expand Up @@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 6
#define V8_MINOR_VERSION 2
#define V8_BUILD_NUMBER 414
#define V8_PATCH_LEVEL 71
#define V8_PATCH_LEVEL 72

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
6 changes: 6 additions & 0 deletions deps/v8/include/v8.h
Expand Up @@ -7207,6 +7207,12 @@ class V8_EXPORT Isolate {
V8_INLINE int64_t
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes);

/**
* This is a Node.js 8.x specific version of the function that uses
* CheckMemoryPressure.
*/
int64_t AdjustAmountOfExternalAllocatedMemoryCustom(int64_t change_in_bytes);

/**
* Returns the number of phantom handles without callbacks that were reset
* by the garbage collector since the last call to this function.
Expand Down
34 changes: 34 additions & 0 deletions deps/v8/src/api.cc
Expand Up @@ -8879,6 +8879,40 @@ void Isolate::GetStackSample(const RegisterState& state, void** frames,
sample_info->external_callback_entry = nullptr;
}

int64_t Isolate::AdjustAmountOfExternalAllocatedMemoryCustom(
int64_t change_in_bytes) {
const int64_t kMemoryReducerActivationLimit = 1024 * 1024;
typedef internal::Internals I;
int64_t* external_memory = reinterpret_cast<int64_t*>(
reinterpret_cast<uint8_t*>(this) + I::kExternalMemoryOffset);
int64_t* external_memory_limit = reinterpret_cast<int64_t*>(
reinterpret_cast<uint8_t*>(this) + I::kExternalMemoryLimitOffset);
int64_t* external_memory_at_last_mc =
reinterpret_cast<int64_t*>(reinterpret_cast<uint8_t*>(this) +
I::kExternalMemoryAtLastMarkCompactOffset);
const int64_t amount = *external_memory + change_in_bytes;

*external_memory = amount;

int64_t allocation_diff_since_last_mc =
*external_memory_at_last_mc - *external_memory;
allocation_diff_since_last_mc = allocation_diff_since_last_mc < 0
? -allocation_diff_since_last_mc
: allocation_diff_since_last_mc;
if (allocation_diff_since_last_mc > kMemoryReducerActivationLimit) {
CheckMemoryPressure();
}

if (change_in_bytes < 0) {
*external_memory_limit += change_in_bytes;
}

if (change_in_bytes > 0 && amount > *external_memory_limit) {
ReportExternalAllocationLimitReached();
}
return *external_memory;
}

size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
size_t result = isolate->global_handles()->NumberOfPhantomHandleResets();
Expand Down
2 changes: 1 addition & 1 deletion src/node_api.cc
Expand Up @@ -3326,7 +3326,7 @@ napi_status napi_adjust_external_memory(napi_env env,
CHECK_ENV(env);
CHECK_ARG(env, adjusted_value);

*adjusted_value = env->isolate->AdjustAmountOfExternalAllocatedMemory(
*adjusted_value = env->isolate->AdjustAmountOfExternalAllocatedMemoryCustom(
change_in_bytes);

return napi_clear_last_error(env);
Expand Down
4 changes: 2 additions & 2 deletions src/node_buffer.cc
Expand Up @@ -143,7 +143,7 @@ CallbackInfo::CallbackInfo(Isolate* isolate,
persistent_.SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);
persistent_.SetWrapperClassId(BUFFER_ID);
persistent_.MarkIndependent();
isolate->AdjustAmountOfExternalAllocatedMemory(sizeof(*this));
isolate->AdjustAmountOfExternalAllocatedMemoryCustom(sizeof(*this));
}


Expand All @@ -163,7 +163,7 @@ void CallbackInfo::WeakCallback(
void CallbackInfo::WeakCallback(Isolate* isolate) {
callback_(data_, hint_);
int64_t change_in_bytes = -static_cast<int64_t>(sizeof(*this));
isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
isolate->AdjustAmountOfExternalAllocatedMemoryCustom(change_in_bytes);
}


Expand Down
2 changes: 1 addition & 1 deletion src/node_crypto.cc
Expand Up @@ -2789,7 +2789,7 @@ void SSLWrap<Base>::DestroySSL() {
return;

SSL_free(ssl_);
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
env_->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(-kExternalSize);
ssl_ = nullptr;
}

Expand Down
7 changes: 4 additions & 3 deletions src/node_crypto.h
Expand Up @@ -168,15 +168,16 @@ class SecureContext : public BaseObject {
cert_(nullptr),
issuer_(nullptr) {
MakeWeak<SecureContext>(this);
env->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
env->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(kExternalSize);
}

void FreeCTXMem() {
if (!ctx_) {
return;
}

env()->isolate()->AdjustAmountOfExternalAllocatedMemory(-kExternalSize);
env()->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(
-kExternalSize);
SSL_CTX_free(ctx_);
if (cert_ != nullptr)
X509_free(cert_);
Expand Down Expand Up @@ -208,7 +209,7 @@ class SSLWrap {
cert_cb_arg_(nullptr),
cert_cb_running_(false) {
ssl_ = SSL_new(sc->ctx_);
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(kExternalSize);
env_->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(kExternalSize);
CHECK_NE(ssl_, nullptr);
}

Expand Down
4 changes: 2 additions & 2 deletions src/node_crypto_bio.h
Expand Up @@ -135,14 +135,14 @@ class NodeBIO {
next_(nullptr) {
data_ = new char[len];
if (env_ != nullptr)
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(len);
env_->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(len);
}

~Buffer() {
delete[] data_;
if (env_ != nullptr) {
const int64_t len = static_cast<int64_t>(len_);
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-len);
env_->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(-len);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/node_process.cc
Expand Up @@ -168,7 +168,7 @@ void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
fields[0] = rss;
fields[1] = v8_heap_stats.total_heap_size();
fields[2] = v8_heap_stats.used_heap_size();
fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
fields[3] = isolate->AdjustAmountOfExternalAllocatedMemoryCustom(0);
}

// Most of the time, it's best to use `console.error` to write
Expand Down
10 changes: 6 additions & 4 deletions src/node_zlib.cc
Expand Up @@ -109,12 +109,14 @@ class ZCtx : public AsyncWrap {
if (mode_ == DEFLATE || mode_ == GZIP || mode_ == DEFLATERAW) {
(void)deflateEnd(&strm_);
int64_t change_in_bytes = -static_cast<int64_t>(kDeflateContextSize);
env()->isolate()->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
env()->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(
change_in_bytes);
} else if (mode_ == INFLATE || mode_ == GUNZIP || mode_ == INFLATERAW ||
mode_ == UNZIP) {
(void)inflateEnd(&strm_);
int64_t change_in_bytes = -static_cast<int64_t>(kInflateContextSize);
env()->isolate()->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
env()->isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(
change_in_bytes);
}
mode_ = NONE;

Expand Down Expand Up @@ -536,15 +538,15 @@ class ZCtx : public AsyncWrap {
ctx->memLevel_,
ctx->strategy_);
ctx->env()->isolate()
->AdjustAmountOfExternalAllocatedMemory(kDeflateContextSize);
->AdjustAmountOfExternalAllocatedMemoryCustom(kDeflateContextSize);
break;
case INFLATE:
case GUNZIP:
case INFLATERAW:
case UNZIP:
ctx->err_ = inflateInit2(&ctx->strm_, ctx->windowBits_);
ctx->env()->isolate()
->AdjustAmountOfExternalAllocatedMemory(kInflateContextSize);
->AdjustAmountOfExternalAllocatedMemoryCustom(kInflateContextSize);
break;
default:
UNREACHABLE();
Expand Down
4 changes: 2 additions & 2 deletions src/string_bytes.cc
Expand Up @@ -66,7 +66,7 @@ class ExternString: public ResourceType {
public:
~ExternString() override {
free(const_cast<TypeName*>(data_));
isolate()->AdjustAmountOfExternalAllocatedMemory(-byte_length());
isolate()->AdjustAmountOfExternalAllocatedMemoryCustom(-byte_length());
}

const TypeName* data() const override {
Expand Down Expand Up @@ -122,7 +122,7 @@ class ExternString: public ResourceType {
data,
length);
MaybeLocal<Value> str = NewExternal(isolate, h_str);
isolate->AdjustAmountOfExternalAllocatedMemory(h_str->byte_length());
isolate->AdjustAmountOfExternalAllocatedMemoryCustom(h_str->byte_length());

if (str.IsEmpty()) {
delete h_str;
Expand Down

0 comments on commit dc1bd96

Please sign in to comment.