Skip to content

Commit

Permalink
Merge pull request #35 from yxping/master
Browse files Browse the repository at this point in the history
[Fix] memory leak caused by JSBinding
  • Loading branch information
hxxft authored May 11, 2018
2 parents 258178f + 7810506 commit 9f2ef70
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 112 deletions.
27 changes: 14 additions & 13 deletions Core/runtime/base/lynx_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,32 @@ namespace jscore {

void LynxObject::SetObjectWrap(ObjectWrap* object_wrap) {
object_wrap_ = object_wrap;
while (protect_times_ > 0) {
object_wrap_->Protect();
protect_times_--;
}
// Register dynamic function
for (auto it = methods_.begin(); it != methods_.end(); ++it) {
object_wrap_->RegisterMethodCallback(it->first, it->second);
if (object_wrap != NULL) {
for (int i = 0; i < protect_times_; i++) {
object_wrap_->Protect();
}
// Register dynamic function
for (auto it = methods_.begin(); it != methods_.end(); ++it) {
object_wrap_->RegisterMethodCallback(it->first, it->second);
}
OnJSObjectAttached();
} else {
OnJSObjectDetached();
}
OnJSObjectAttached();
}

void LynxObject::ProtectJSObject() {
if (object_wrap_ != NULL) {
object_wrap_->Protect();
} else {
protect_times_++;
}
protect_times_++;
}

void LynxObject::UnprotectJSObject() {
if (object_wrap_ != NULL) {
object_wrap_->Unprotect();
} else {
protect_times_--;
}
protect_times_--;
}

}
}
7 changes: 5 additions & 2 deletions Core/runtime/base/lynx_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <unordered_map>
#include <vector>

#include "base/scoped_ptr.h"
#include "base/ref_counted_ptr.h"
#include "runtime/js/defines.h"

namespace jscore {
Expand All @@ -17,7 +17,7 @@ namespace jscore {
class ClassTemplate;
class JSContext;

class LynxObject {
class LynxObject : public base::RefCountPtr<LynxObject> {

public:

Expand Down Expand Up @@ -48,6 +48,7 @@ namespace jscore {
void ProtectJSObject();
void UnprotectJSObject();
virtual void OnJSObjectAttached() {}
virtual void OnJSObjectDetached() {}

protected:
JSContext* context_;
Expand All @@ -58,6 +59,8 @@ namespace jscore {

std::unordered_map<std::string, JSMethodCallback> methods_;
int protect_times_;

DISALLOW_COPY_AND_ASSIGN(LynxObject);
};
}

Expand Down
13 changes: 7 additions & 6 deletions Core/runtime/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ namespace jscore {
}

Canvas::~Canvas() {
context_2d_->UnprotectJSObject();
if (context_2d_.Get() != NULL) {
context_2d_->UnprotectJSObject();
}
}

base::ScopedPtr<LynxValue> Canvas::GetContext(base::ScopedPtr<LynxArray>& array) {
if(context_2d_ == NULL) {
if(context_2d_.Get() == NULL) {
context_2d_ = lynx_new Canvas2DContext(context(), render_object());
context_2d_->ProtectJSObject();
}

context_2d_->ProtectJSObject();
return base::ScopedPtr<LynxValue>(LynxValue::MakeObject(context_2d_));
return base::ScopedPtr<LynxValue>(LynxValue::MakeObject(context_2d_.Get()));
}
}
}
2 changes: 1 addition & 1 deletion Core/runtime/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace jscore {
base::ScopedPtr<LynxValue> GetContext(base::ScopedPtr<LynxArray>& array);

private:
Canvas2DContext* context_2d_;
base::ScopedRefPtr<Canvas2DContext> context_2d_;

};
}
Expand Down
9 changes: 5 additions & 4 deletions Core/runtime/document.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ namespace jscore {

Document::Document(JSContext* context) : LynxObject(context, DEFAULT_CLASS_TEMPLATE(context)){
body_ = lynx_new Element(context, context->runtime()->render_tree_host()->render_root());
body_->ProtectJSObject();
}

Document::~Document() {

body_->UnprotectJSObject();
}

Element* Document::CreateElement(std::string &tag_name) {
Expand Down Expand Up @@ -85,7 +86,7 @@ namespace jscore {
if(array.Get() != NULL && array->Size() > 0) {
std::string text = array->Get(0)->data_.str;
return LynxValue::MakeObject(QuerySelector(text));
}
}
return base::ScopedPtr<LynxValue>(NULL);
}

Expand Down Expand Up @@ -172,7 +173,7 @@ namespace jscore {
}

base::ScopedPtr<LynxValue> Document::GetBody() {
return LynxValue::MakeObject(body_);
return LynxValue::MakeObject(body_.Get());
}

void Document::SetDomain(base::ScopedPtr<jscore::LynxValue> value) {
Expand All @@ -198,4 +199,4 @@ namespace jscore {
void Document::SetOnTouchMove(base::ScopedPtr<jscore::LynxValue> value) {

}
}
}
2 changes: 1 addition & 1 deletion Core/runtime/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace jscore {
void SetOnTouchMove(base::ScopedPtr<jscore::LynxValue> value);

private:
Element* body_;
base::ScopedRefPtr<Element> body_;
};
}

Expand Down
10 changes: 5 additions & 5 deletions Core/runtime/global.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,23 +106,23 @@ namespace jscore {
}

base::ScopedPtr<LynxValue> Global::GetConsole() {
return LynxValue::MakeObject(console_);
return LynxValue::MakeObject(console());
}

base::ScopedPtr<LynxValue> Global::GetNavigator() {
return LynxValue::MakeObject(navigator_);
return LynxValue::MakeObject(navigator());
}

base::ScopedPtr<LynxValue> Global::GetScreen() {
return LynxValue::MakeObject(screen_);
return LynxValue::MakeObject(screen());
}

base::ScopedPtr<LynxValue> Global::GetLoader() {
return LynxValue::MakeObject(loader_);
return LynxValue::MakeObject(loader());
}

base::ScopedPtr<LynxValue> Global::GetDocument() {
return LynxValue::MakeObject(document_);
return LynxValue::MakeObject(document());
}

}
Expand Down
21 changes: 11 additions & 10 deletions Core/runtime/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ namespace jscore {
Global(JSContext* context);
virtual ~Global();
void OnJSObjectAttached();
inline Console* console() { return console_; }
inline Navigator* navigator() { return navigator_; }
inline Screen* screen() { return screen_; }
inline Loader* loader() { return loader_; }
inline Document* document() { return document_; }
inline Console* console() { return console_.Get(); }
inline Navigator* navigator() { return navigator_.Get(); }
inline Screen* screen() { return screen_.Get(); }
inline Loader* loader() { return loader_.Get(); }
inline Document* document() { return document_.Get(); }

base::ScopedPtr<LynxValue> SetTimeout(base::ScopedPtr<LynxArray> &array);
base::ScopedPtr<LynxValue> SetInterval(base::ScopedPtr<LynxArray> &array);
Expand All @@ -36,12 +36,13 @@ namespace jscore {
base::ScopedPtr<LynxValue> GetDocument();

private:
Console* console_;
Navigator* navigator_;
Screen* screen_;
Loader* loader_;
Document* document_;
base::ScopedRefPtr<Console> console_;
base::ScopedRefPtr<Navigator> navigator_;
base::ScopedRefPtr<Screen> screen_;
base::ScopedRefPtr<Loader> loader_;
base::ScopedRefPtr<Document> document_;

DISALLOW_COPY_AND_ASSIGN(Global);
};
}

Expand Down
1 change: 1 addition & 0 deletions Core/runtime/js/class_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace jscore {
public:
class PrototypeBuilder {
public:
virtual ~PrototypeBuilder() {}
virtual void FinishCreation(ClassTemplate* class_template) = 0;
};

Expand Down
13 changes: 13 additions & 0 deletions Core/runtime/js/js_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@

#include "runtime/js/js_context.h"
#include "runtime/runtime.h"
#include "runtime/global.h"

namespace jscore {

JSContext::JSContext() : runtime_(NULL),
vm_(NULL),
ua_(),
class_template_storage_(lynx_new ClassTemplateStorage),
global_(NULL) {

}

JSContext::~JSContext() {
Finalize();
}

void JSContext::OnExceptionOccurred(std::string &error) {
if(runtime_ && runtime_->exception_handler()){
runtime_->exception_handler()->OnReceiveResult(error);
Expand Down
15 changes: 3 additions & 12 deletions Core/runtime/js/js_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,9 @@ class Global;
class LynxObjectPlatform;
class JSContext : public base::RefCountPtr<Runtime> {
public:
JSContext()
: runtime_(NULL),
vm_(NULL),
ua_(),
class_template_storage_(lynx_new ClassTemplateStorage),
global_(NULL) {
JSContext();

}

virtual ~JSContext() {
Finalize();
}
virtual ~JSContext();

virtual void Initialize(JSVM* vm, Runtime* runtime) {
vm_ = vm;
Expand Down Expand Up @@ -85,7 +76,7 @@ class JSContext : public base::RefCountPtr<Runtime> {
base::ObserverList observers_;
UserAgent ua_;
base::ScopedPtr<ClassTemplateStorage> class_template_storage_;
Global* global_;
Global* global_; // Should release in subclass before real js context release!

DISALLOW_COPY_AND_ASSIGN(JSContext);
};
Expand Down
4 changes: 2 additions & 2 deletions Core/runtime/js/object_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#ifndef LYNX_RUNTIME_JS_OBJECT_WRAP_H_
#define LYNX_RUNTIME_JS_OBJECT_WRAP_H_

#include "base/scoped_ptr.h"
#include "base/ref_counted_ptr.h"
#include "base/observer/observer.h"
#include "base/debug/memory_debug.h"
#include "runtime/js/base.h"
Expand Down Expand Up @@ -38,7 +38,7 @@ namespace jscore {
virtual void OnJSObjectFinalize() = 0;

JSContext* context_;
base::ScopedPtr<LynxObject> lynx_object_;
base::ScopedRefPtr<LynxObject> lynx_object_;

friend class LynxObject;

Expand Down
10 changes: 7 additions & 3 deletions Core/runtime/jsc/jsc_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace jscore {
}

JSCContext::~JSCContext() {
// Global should be release before context release
global_->Release();
global_ = NULL;
JSGlobalContextRef temp = context_;
context_ = NULL;
JSGlobalContextRelease(temp);
Expand All @@ -31,14 +34,15 @@ namespace jscore {
JSContextGroupRef context_group = static_cast<JSContextGroupRef>(vm->vm());

global_ = lynx_new Global(this);
global_->AddRef();
JSCPrototypeBuilder *global_prototype_builder = static_cast<JSCPrototypeBuilder*>(
global_->class_template()->prototype_builder());
global_prototype_builder->SetJSClassAttributes(kJSClassAttributeNoAutomaticPrototype);
context_ = JSGlobalContextCreateInGroup(context_group, global_prototype_builder->class_ref());

JSObjectRef global_object = JSContextGetGlobalObject(context_);
JSCObjectWrap::Wrap(this, global_, global_object);

JSCObjectWrap::Wrap(this, global(), global_object);
JSCHelper::SetValueProperty(context_, global_object, "window", global_object,
kJSPropertyAttributeNone, 0);
JSCHelper::SetValueProperty(context_, global_object, "global", global_object,
Expand Down
1 change: 1 addition & 0 deletions Core/runtime/jsc/object_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace jscore {
}

void JSCObjectWrap::OnJSObjectFinalize() {
lynx_object_->SetObjectWrap(NULL);
assert(JSObjectSetPrivate(js_object_, NULL));
lynx_delete(this);
}
Expand Down
1 change: 1 addition & 0 deletions Core/runtime/v8/object_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace jscore {
}

void V8ObjectWrap::OnJSObjectFinalize() {
lynx_object_->SetObjectWrap(NULL);
lynx_delete(this);
}
}
5 changes: 4 additions & 1 deletion Core/runtime/v8/v8_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
namespace jscore {

V8Context::~V8Context() {
// Global should be release before context release
global_->Release();
Clear();
context_.Reset();
}
Expand All @@ -36,13 +38,14 @@ void V8Context::Initialize(JSVM* vm, Runtime* runtime) {
v8::V8::AddMessageListener(V8Context::OnUncaughtError);

global_ = lynx_new Global(this);
global_->AddRef();
auto global_template = static_cast<V8PrototypeBuilder*>(
global_->class_template()->prototype_builder())->GetClass(isolate)->InstanceTemplate();
auto context = v8::Context::New(isolate, nullptr, global_template);
v8::Context::Scope context_scope(context);
context_.Reset(isolate, context);
auto global_object = context->Global();
V8ObjectWrap::Wrap(this, global_, global_object);
V8ObjectWrap::Wrap(this, global(), global_object);
global_object->Set(context, V8Helper::ConvertToV8String(isolate, "global"),
global_object).FromJust();
global_object->Set(context, V8Helper::ConvertToV8String(isolate, "window"),
Expand Down
Loading

0 comments on commit 9f2ef70

Please sign in to comment.