Revert "Require V8 to be explicitly initialized before an Isolate is created"
LOG=n TBR=svenpanne@chromium.org BUG=none Review URL: https://codereview.chromium.org/582953002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24055 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b471347b65
commit
525ed1130e
30
include/v8.h
30
include/v8.h
@ -4344,12 +4344,13 @@ typedef void (*JitCodeEventHandler)(const JitCodeEvent* event);
|
||||
|
||||
|
||||
/**
|
||||
* Isolate represents an isolated instance of the V8 engine. V8 isolates have
|
||||
* completely separate states. Objects from one isolate must not be used in
|
||||
* other isolates. The embedder can create multiple isolates and use them in
|
||||
* parallel in multiple threads. An isolate can be entered by at most one
|
||||
* thread at any given time. The Locker/Unlocker API must be used to
|
||||
* synchronize.
|
||||
* Isolate represents an isolated instance of the V8 engine. V8
|
||||
* isolates have completely separate states. Objects from one isolate
|
||||
* must not be used in other isolates. When V8 is initialized a
|
||||
* default isolate is implicitly created and entered. The embedder
|
||||
* can create additional isolates and use them in parallel in multiple
|
||||
* threads. An isolate can be entered by at most one thread at any
|
||||
* given time. The Locker/Unlocker API must be used to synchronize.
|
||||
*/
|
||||
class V8_EXPORT Isolate {
|
||||
public:
|
||||
@ -4357,10 +4358,7 @@ class V8_EXPORT Isolate {
|
||||
* Initial configuration parameters for a new Isolate.
|
||||
*/
|
||||
struct CreateParams {
|
||||
CreateParams()
|
||||
: entry_hook(NULL),
|
||||
code_event_handler(NULL),
|
||||
enable_serializer(false) {}
|
||||
CreateParams() : entry_hook(NULL), code_event_handler(NULL) {}
|
||||
|
||||
/**
|
||||
* The optional entry_hook allows the host application to provide the
|
||||
@ -4381,11 +4379,6 @@ class V8_EXPORT Isolate {
|
||||
* ResourceConstraints to use for the new Isolate.
|
||||
*/
|
||||
ResourceConstraints constraints;
|
||||
|
||||
/**
|
||||
* This flag currently renders the Isolate unusable.
|
||||
*/
|
||||
bool enable_serializer;
|
||||
};
|
||||
|
||||
|
||||
@ -4496,8 +4489,6 @@ class V8_EXPORT Isolate {
|
||||
*
|
||||
* When an isolate is no longer used its resources should be freed
|
||||
* by calling Dispose(). Using the delete operator is not allowed.
|
||||
*
|
||||
* V8::Initialize() must have run prior to this.
|
||||
*/
|
||||
static Isolate* New(const CreateParams& params = CreateParams());
|
||||
|
||||
@ -5111,8 +5102,9 @@ class V8_EXPORT V8 {
|
||||
static void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
|
||||
|
||||
/**
|
||||
* Initializes V8. This function needs to be called before the first Isolate
|
||||
* is created. It always returns true.
|
||||
* Initializes from snapshot if possible. Otherwise, attempts to
|
||||
* initialize from scratch. This function is called implicitly if
|
||||
* you use the API without calling it first.
|
||||
*/
|
||||
static bool Initialize();
|
||||
|
||||
|
@ -257,7 +257,6 @@ int main(int argc, char* argv[]) {
|
||||
v8::V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
int result = RunMain(argc, argv);
|
||||
v8::V8::Dispose();
|
||||
v8::V8::ShutdownPlatform();
|
||||
|
@ -648,7 +648,6 @@ int main(int argc, char* argv[]) {
|
||||
v8::V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
map<string, string> options;
|
||||
string file;
|
||||
ParseOptions(argc, argv, &options, &file);
|
||||
|
@ -83,7 +83,6 @@ int main(int argc, char* argv[]) {
|
||||
v8::V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
ShellArrayBufferAllocator array_buffer_allocator;
|
||||
v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
|
||||
|
74
src/api.cc
74
src/api.cc
@ -202,6 +202,29 @@ static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
// --- S t a t i c s ---
|
||||
|
||||
|
||||
static bool InitializeHelper(i::Isolate* isolate) {
|
||||
// If the isolate has a function entry hook, it needs to re-build all its
|
||||
// code stubs with entry hooks embedded, so let's deserialize a snapshot.
|
||||
if (isolate == NULL || isolate->function_entry_hook() == NULL) {
|
||||
if (i::Snapshot::Initialize())
|
||||
return true;
|
||||
}
|
||||
return i::V8::Initialize(NULL);
|
||||
}
|
||||
|
||||
|
||||
static inline bool EnsureInitializedForIsolate(i::Isolate* isolate,
|
||||
const char* location) {
|
||||
return (isolate != NULL && isolate->IsInitialized()) ||
|
||||
Utils::ApiCheck(InitializeHelper(isolate),
|
||||
location,
|
||||
"Error initializing V8");
|
||||
}
|
||||
|
||||
|
||||
StartupDataDecompressor::StartupDataDecompressor()
|
||||
: raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
|
||||
for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
|
||||
@ -723,6 +746,7 @@ void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
|
||||
// NeanderObject constructor. When you add one to the site calling the
|
||||
// constructor you should check that you ensured the VM was not dead first.
|
||||
NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
|
||||
EnsureInitializedForIsolate(isolate, "v8::Nowhere");
|
||||
ENTER_V8(isolate);
|
||||
value_ = isolate->factory()->NewNeanderObject();
|
||||
i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
|
||||
@ -915,6 +939,7 @@ Local<FunctionTemplate> FunctionTemplate::New(
|
||||
v8::Handle<Signature> signature,
|
||||
int length) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::FunctionTemplate::New()");
|
||||
LOG_API(i_isolate, "FunctionTemplate::New");
|
||||
ENTER_V8(i_isolate);
|
||||
return FunctionTemplateNew(
|
||||
@ -926,6 +951,7 @@ Local<Signature> Signature::New(Isolate* isolate,
|
||||
Handle<FunctionTemplate> receiver, int argc,
|
||||
Handle<FunctionTemplate> argv[]) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::Signature::New()");
|
||||
LOG_API(i_isolate, "Signature::New");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::Struct> struct_obj =
|
||||
@ -1076,6 +1102,7 @@ Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
|
||||
|
||||
Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
|
||||
LOG_API(isolate, "TypeSwitch::New");
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
|
||||
@ -1256,6 +1283,7 @@ Local<ObjectTemplate> ObjectTemplate::New() {
|
||||
Local<ObjectTemplate> ObjectTemplate::New(
|
||||
i::Isolate* isolate,
|
||||
v8::Handle<FunctionTemplate> constructor) {
|
||||
EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
|
||||
LOG_API(isolate, "ObjectTemplate::New");
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::Struct> struct_obj =
|
||||
@ -2372,6 +2400,7 @@ bool StackFrame::IsConstructor() const {
|
||||
Local<Value> JSON::Parse(Local<String> json_string) {
|
||||
i::Handle<i::String> string = Utils::OpenHandle(*json_string);
|
||||
i::Isolate* isolate = string->GetIsolate();
|
||||
EnsureInitializedForIsolate(isolate, "v8::JSON::Parse");
|
||||
ENTER_V8(isolate);
|
||||
i::HandleScope scope(isolate);
|
||||
i::Handle<i::String> source = i::String::Flatten(string);
|
||||
@ -4862,6 +4891,7 @@ int String::Write(uint16_t* buffer,
|
||||
|
||||
bool v8::String::IsExternal() const {
|
||||
i::Handle<i::String> str = Utils::OpenHandle(this);
|
||||
EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
|
||||
return i::StringShape(*str).IsExternalTwoByte();
|
||||
}
|
||||
|
||||
@ -5050,8 +5080,11 @@ void v8::V8::ShutdownPlatform() {
|
||||
|
||||
|
||||
bool v8::V8::Initialize() {
|
||||
i::V8::Initialize();
|
||||
return true;
|
||||
i::Isolate* isolate = i::Isolate::UncheckedCurrent();
|
||||
if (isolate != NULL && isolate->IsInitialized()) {
|
||||
return true;
|
||||
}
|
||||
return InitializeHelper(isolate);
|
||||
}
|
||||
|
||||
|
||||
@ -5246,6 +5279,7 @@ Local<Context> v8::Context::New(
|
||||
v8::Handle<ObjectTemplate> global_template,
|
||||
v8::Handle<Value> global_object) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
|
||||
EnsureInitializedForIsolate(isolate, "v8::Context::New()");
|
||||
LOG_API(isolate, "Context::New");
|
||||
ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
|
||||
i::HandleScope scope(isolate);
|
||||
@ -5376,6 +5410,7 @@ bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
|
||||
Local<External> v8::External::New(Isolate* isolate, void* value) {
|
||||
STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::External::New()");
|
||||
LOG_API(i_isolate, "External::New");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
|
||||
@ -5450,6 +5485,7 @@ inline Local<String> NewString(Isolate* v8_isolate,
|
||||
String::NewStringType type,
|
||||
int length) {
|
||||
i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
|
||||
EnsureInitializedForIsolate(isolate, location);
|
||||
LOG_API(isolate, env);
|
||||
if (length == 0 && type != String::kUndetectableString) {
|
||||
return String::Empty(v8_isolate);
|
||||
@ -5512,6 +5548,7 @@ Local<String> String::NewFromTwoByte(Isolate* isolate,
|
||||
Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
|
||||
i::Handle<i::String> left_string = Utils::OpenHandle(*left);
|
||||
i::Isolate* isolate = left_string->GetIsolate();
|
||||
EnsureInitializedForIsolate(isolate, "v8::String::New()");
|
||||
LOG_API(isolate, "String::New(char)");
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::String> right_string = Utils::OpenHandle(*right);
|
||||
@ -5544,6 +5581,7 @@ Local<String> v8::String::NewExternal(
|
||||
Isolate* isolate,
|
||||
v8::String::ExternalStringResource* resource) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()");
|
||||
LOG_API(i_isolate, "String::NewExternal");
|
||||
ENTER_V8(i_isolate);
|
||||
CHECK(resource && resource->data());
|
||||
@ -5582,6 +5620,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
||||
Local<String> v8::String::NewExternal(
|
||||
Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()");
|
||||
LOG_API(i_isolate, "String::NewExternal");
|
||||
ENTER_V8(i_isolate);
|
||||
CHECK(resource && resource->data());
|
||||
@ -5634,6 +5673,7 @@ bool v8::String::CanMakeExternal() {
|
||||
|
||||
Local<v8::Object> v8::Object::New(Isolate* isolate) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::Object::New()");
|
||||
LOG_API(i_isolate, "Object::New");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::JSObject> obj =
|
||||
@ -5644,6 +5684,7 @@ Local<v8::Object> v8::Object::New(Isolate* isolate) {
|
||||
|
||||
Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::NumberObject::New()");
|
||||
LOG_API(i_isolate, "NumberObject::New");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
|
||||
@ -5664,6 +5705,7 @@ double v8::NumberObject::ValueOf() const {
|
||||
|
||||
Local<v8::Value> v8::BooleanObject::New(bool value) {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::BooleanObject::New()");
|
||||
LOG_API(isolate, "BooleanObject::New");
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::Object> boolean(value
|
||||
@ -5688,6 +5730,7 @@ bool v8::BooleanObject::ValueOf() const {
|
||||
Local<v8::Value> v8::StringObject::New(Handle<String> value) {
|
||||
i::Handle<i::String> string = Utils::OpenHandle(*value);
|
||||
i::Isolate* isolate = string->GetIsolate();
|
||||
EnsureInitializedForIsolate(isolate, "v8::StringObject::New()");
|
||||
LOG_API(isolate, "StringObject::New");
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::Object> obj =
|
||||
@ -5708,6 +5751,7 @@ Local<v8::String> v8::StringObject::ValueOf() const {
|
||||
|
||||
Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::SymbolObject::New()");
|
||||
LOG_API(i_isolate, "SymbolObject::New");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::Object> obj = i::Object::ToObject(
|
||||
@ -5728,6 +5772,7 @@ Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
|
||||
|
||||
Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::Date::New()");
|
||||
LOG_API(i_isolate, "Date::New");
|
||||
if (std::isnan(time)) {
|
||||
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
|
||||
@ -5793,6 +5838,7 @@ static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
|
||||
Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
|
||||
Flags flags) {
|
||||
i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
|
||||
EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
|
||||
LOG_API(isolate, "RegExp::New");
|
||||
ENTER_V8(isolate);
|
||||
EXCEPTION_PREAMBLE(isolate);
|
||||
@ -5829,6 +5875,7 @@ v8::RegExp::Flags v8::RegExp::GetFlags() const {
|
||||
|
||||
Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::Array::New()");
|
||||
LOG_API(i_isolate, "Array::New");
|
||||
ENTER_V8(i_isolate);
|
||||
int real_length = length > 0 ? length : 0;
|
||||
@ -6048,6 +6095,7 @@ size_t v8::ArrayBuffer::ByteLength() const {
|
||||
|
||||
Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(size_t)");
|
||||
LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::JSArrayBuffer> obj =
|
||||
@ -6060,6 +6108,7 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
|
||||
Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
|
||||
size_t byte_length) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
|
||||
LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::JSArrayBuffer> obj =
|
||||
@ -6162,6 +6211,8 @@ i::Handle<i::JSTypedArray> NewTypedArray(
|
||||
Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
|
||||
size_t byte_offset, size_t length) { \
|
||||
i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
|
||||
EnsureInitializedForIsolate(isolate, \
|
||||
"v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
|
||||
LOG_API(isolate, \
|
||||
"v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
|
||||
ENTER_V8(isolate); \
|
||||
@ -6185,6 +6236,8 @@ Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
|
||||
size_t byte_offset, size_t byte_length) {
|
||||
i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
|
||||
i::Isolate* isolate = buffer->GetIsolate();
|
||||
EnsureInitializedForIsolate(
|
||||
isolate, "v8::DataView::New(void*, size_t, size_t)");
|
||||
LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
|
||||
@ -6196,6 +6249,7 @@ Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
|
||||
|
||||
Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::Symbol::New()");
|
||||
LOG_API(i_isolate, "Symbol::New()");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
|
||||
@ -6260,6 +6314,7 @@ Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
|
||||
|
||||
Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
EnsureInitializedForIsolate(i_isolate, "v8::Private::New()");
|
||||
LOG_API(i_isolate, "Private::New()");
|
||||
ENTER_V8(i_isolate);
|
||||
i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
|
||||
@ -6331,6 +6386,7 @@ Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
|
||||
|
||||
bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
|
||||
ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
|
||||
ENTER_V8(isolate);
|
||||
i::HandleScope scope(isolate);
|
||||
@ -6346,6 +6402,7 @@ bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
|
||||
|
||||
void V8::RemoveMessageListeners(MessageCallback that) {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
|
||||
ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
|
||||
ENTER_V8(isolate);
|
||||
i::HandleScope scope(isolate);
|
||||
@ -6618,16 +6675,6 @@ Isolate* Isolate::New(const Isolate::CreateParams& params) {
|
||||
}
|
||||
SetResourceConstraints(v8_isolate,
|
||||
const_cast<ResourceConstraints*>(¶ms.constraints));
|
||||
if (params.enable_serializer) {
|
||||
isolate->enable_serializer();
|
||||
}
|
||||
// TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
|
||||
Isolate::Scope isolate_scope(v8_isolate);
|
||||
if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
|
||||
// If the isolate has a function entry hook, it needs to re-build all its
|
||||
// code stubs with entry hooks embedded, so don't deserialize a snapshot.
|
||||
isolate->Init(NULL);
|
||||
}
|
||||
return v8_isolate;
|
||||
}
|
||||
|
||||
@ -6930,6 +6977,7 @@ DEFINE_ERROR(Error)
|
||||
|
||||
bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
|
||||
ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
|
||||
ENTER_V8(isolate);
|
||||
i::HandleScope scope(isolate);
|
||||
@ -6968,6 +7016,7 @@ void Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) {
|
||||
|
||||
void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
|
||||
ENTER_V8(isolate);
|
||||
isolate->debug()->SetMessageHandler(handler);
|
||||
}
|
||||
@ -7041,6 +7090,7 @@ void Debug::ProcessDebugMessages() {
|
||||
|
||||
Local<Context> Debug::GetDebugContext() {
|
||||
i::Isolate* isolate = i::Isolate::Current();
|
||||
EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
|
||||
ENTER_V8(isolate);
|
||||
return Utils::ToLocal(i::Isolate::Current()->debug()->GetDebugContext());
|
||||
}
|
||||
|
@ -125,7 +125,6 @@ int RandomNumberGenerator::Next(int bits) {
|
||||
|
||||
|
||||
void RandomNumberGenerator::SetSeed(int64_t seed) {
|
||||
initial_seed_ = seed;
|
||||
seed_ = (seed ^ kMultiplier) & kMask;
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,6 @@ class RandomNumberGenerator FINAL {
|
||||
// Override the current ssed.
|
||||
void SetSeed(int64_t seed);
|
||||
|
||||
int64_t initial_seed() const { return initial_seed_; }
|
||||
|
||||
private:
|
||||
static const int64_t kMultiplier = V8_2PART_UINT64_C(0x5, deece66d);
|
||||
static const int64_t kAddend = 0xb;
|
||||
@ -83,7 +81,6 @@ class RandomNumberGenerator FINAL {
|
||||
|
||||
int Next(int bits) WARN_UNUSED_RESULT;
|
||||
|
||||
int64_t initial_seed_;
|
||||
int64_t seed_;
|
||||
};
|
||||
|
||||
|
@ -2594,6 +2594,9 @@ Genesis::Genesis(Isolate* isolate,
|
||||
active_(isolate->bootstrapper()) {
|
||||
NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
|
||||
result_ = Handle<Context>::null();
|
||||
// If V8 cannot be initialized, just return.
|
||||
if (!V8::Initialize(NULL)) return;
|
||||
|
||||
// Before creating the roots we must save the context and restore it
|
||||
// on all function exits.
|
||||
SaveContext saved_context(isolate);
|
||||
|
@ -1619,7 +1619,6 @@ int Shell::Main(int argc, char* argv[]) {
|
||||
v8::V8::InitializeICU(options.icu_data_file);
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
|
||||
StartupDataHandler startup_data(options.natives_blob, options.snapshot_blob);
|
||||
#endif
|
||||
|
@ -48,6 +48,7 @@ int ThreadId::AllocateThreadId() {
|
||||
|
||||
|
||||
int ThreadId::GetCurrentThreadId() {
|
||||
Isolate::EnsureInitialized();
|
||||
int thread_id = base::Thread::GetThreadLocalInt(Isolate::thread_id_key_);
|
||||
if (thread_id == 0) {
|
||||
thread_id = AllocateThreadId();
|
||||
@ -113,16 +114,17 @@ base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
|
||||
#ifdef DEBUG
|
||||
base::Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key;
|
||||
#endif // DEBUG
|
||||
base::LazyMutex Isolate::thread_data_table_mutex_ = LAZY_MUTEX_INITIALIZER;
|
||||
base::LazyMutex Isolate::process_wide_mutex_ = LAZY_MUTEX_INITIALIZER;
|
||||
Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
|
||||
base::Atomic32 Isolate::isolate_counter_ = 0;
|
||||
|
||||
Isolate::PerIsolateThreadData*
|
||||
Isolate::FindOrAllocatePerThreadDataForThisThread() {
|
||||
EnsureInitialized();
|
||||
ThreadId thread_id = ThreadId::Current();
|
||||
PerIsolateThreadData* per_thread = NULL;
|
||||
{
|
||||
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
|
||||
base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer());
|
||||
per_thread = thread_data_table_->Lookup(this, thread_id);
|
||||
if (per_thread == NULL) {
|
||||
per_thread = new PerIsolateThreadData(this, thread_id);
|
||||
@ -142,26 +144,28 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() {
|
||||
|
||||
Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread(
|
||||
ThreadId thread_id) {
|
||||
EnsureInitialized();
|
||||
PerIsolateThreadData* per_thread = NULL;
|
||||
{
|
||||
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
|
||||
base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer());
|
||||
per_thread = thread_data_table_->Lookup(this, thread_id);
|
||||
}
|
||||
return per_thread;
|
||||
}
|
||||
|
||||
|
||||
void Isolate::InitializeOncePerProcess() {
|
||||
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
|
||||
CHECK(thread_data_table_ == NULL);
|
||||
isolate_key_ = base::Thread::CreateThreadLocalKey();
|
||||
thread_id_key_ = base::Thread::CreateThreadLocalKey();
|
||||
per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey();
|
||||
void Isolate::EnsureInitialized() {
|
||||
base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer());
|
||||
if (thread_data_table_ == NULL) {
|
||||
isolate_key_ = base::Thread::CreateThreadLocalKey();
|
||||
thread_id_key_ = base::Thread::CreateThreadLocalKey();
|
||||
per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey();
|
||||
#ifdef DEBUG
|
||||
PerThreadAssertScopeBase::thread_local_key =
|
||||
base::Thread::CreateThreadLocalKey();
|
||||
PerThreadAssertScopeBase::thread_local_key =
|
||||
base::Thread::CreateThreadLocalKey();
|
||||
#endif // DEBUG
|
||||
thread_data_table_ = new Isolate::ThreadDataTable();
|
||||
thread_data_table_ = new Isolate::ThreadDataTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1517,10 +1521,6 @@ Isolate::Isolate()
|
||||
stress_deopt_count_(0),
|
||||
next_optimization_id_(0),
|
||||
use_counter_callback_(NULL) {
|
||||
{
|
||||
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
|
||||
CHECK(thread_data_table_);
|
||||
}
|
||||
id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1);
|
||||
TRACE_ISOLATE(constructor);
|
||||
|
||||
@ -1571,7 +1571,7 @@ void Isolate::TearDown() {
|
||||
Deinit();
|
||||
|
||||
{
|
||||
base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
|
||||
base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer());
|
||||
thread_data_table_->RemoveAllThreads(this);
|
||||
}
|
||||
|
||||
@ -1676,6 +1676,7 @@ void Isolate::PushToPartialSnapshotCache(Object* obj) {
|
||||
|
||||
void Isolate::SetIsolateThreadLocals(Isolate* isolate,
|
||||
PerIsolateThreadData* data) {
|
||||
EnsureInitialized();
|
||||
base::Thread::SetThreadLocal(isolate_key_, isolate);
|
||||
base::Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
|
||||
}
|
||||
|
@ -466,17 +466,17 @@ class Isolate {
|
||||
kIsolateAddressCount
|
||||
};
|
||||
|
||||
static void InitializeOncePerProcess();
|
||||
|
||||
// Returns the PerIsolateThreadData for the current thread (or NULL if one is
|
||||
// not currently set).
|
||||
static PerIsolateThreadData* CurrentPerIsolateThreadData() {
|
||||
EnsureInitialized();
|
||||
return reinterpret_cast<PerIsolateThreadData*>(
|
||||
base::Thread::GetThreadLocal(per_isolate_thread_data_key_));
|
||||
}
|
||||
|
||||
// Returns the isolate inside which the current thread is running.
|
||||
INLINE(static Isolate* Current()) {
|
||||
EnsureInitialized();
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(
|
||||
base::Thread::GetExistingThreadLocal(isolate_key_));
|
||||
DCHECK(isolate != NULL);
|
||||
@ -484,6 +484,7 @@ class Isolate {
|
||||
}
|
||||
|
||||
INLINE(static Isolate* UncheckedCurrent()) {
|
||||
EnsureInitialized();
|
||||
return reinterpret_cast<Isolate*>(
|
||||
base::Thread::GetThreadLocal(isolate_key_));
|
||||
}
|
||||
@ -528,11 +529,13 @@ class Isolate {
|
||||
// Used internally for V8 threads that do not execute JavaScript but still
|
||||
// are part of the domain of an isolate (like the context switcher).
|
||||
static base::Thread::LocalStorageKey isolate_key() {
|
||||
EnsureInitialized();
|
||||
return isolate_key_;
|
||||
}
|
||||
|
||||
// Returns the key used to store process-wide thread IDs.
|
||||
static base::Thread::LocalStorageKey thread_id_key() {
|
||||
EnsureInitialized();
|
||||
return thread_id_key_;
|
||||
}
|
||||
|
||||
@ -1107,9 +1110,9 @@ class Isolate {
|
||||
void SetUseCounterCallback(v8::Isolate::UseCounterCallback callback);
|
||||
void CountUsage(v8::Isolate::UseCounterFeature feature);
|
||||
|
||||
static Isolate* NewForTesting() { return new Isolate(); }
|
||||
|
||||
private:
|
||||
static void EnsureInitialized();
|
||||
|
||||
Isolate();
|
||||
|
||||
friend struct GlobalState;
|
||||
@ -1168,7 +1171,8 @@ class Isolate {
|
||||
DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
|
||||
};
|
||||
|
||||
static base::LazyMutex thread_data_table_mutex_;
|
||||
// This mutex protects highest_thread_id_ and thread_data_table_.
|
||||
static base::LazyMutex process_wide_mutex_;
|
||||
|
||||
static base::Thread::LocalStorageKey per_isolate_thread_data_key_;
|
||||
static base::Thread::LocalStorageKey isolate_key_;
|
||||
|
@ -303,6 +303,11 @@ void DumpException(Handle<Message> message) {
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
i::CpuFeatures::Probe(true);
|
||||
|
||||
// By default, log code create information in the snapshot.
|
||||
i::FLAG_log_code = true;
|
||||
|
||||
@ -314,13 +319,6 @@ int main(int argc, char** argv) {
|
||||
i::FlagList::PrintHelp();
|
||||
return !i::FLAG_help;
|
||||
}
|
||||
|
||||
V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
i::CpuFeatures::Probe(true);
|
||||
|
||||
#ifdef COMPRESS_STARTUP_DATA_BZ2
|
||||
BZip2Decompressor natives_decompressor;
|
||||
int bz2_result = natives_decompressor.Decompress();
|
||||
@ -331,11 +329,10 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
i::FLAG_logfile_per_isolate = false;
|
||||
|
||||
Isolate::CreateParams params;
|
||||
params.enable_serializer = true;
|
||||
Isolate* isolate = v8::Isolate::New(params);
|
||||
Isolate* isolate = v8::Isolate::New();
|
||||
{ Isolate::Scope isolate_scope(isolate);
|
||||
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
internal_isolate->enable_serializer();
|
||||
|
||||
Persistent<Context> context;
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) {
|
||||
}
|
||||
|
||||
|
||||
bool Snapshot::Initialize(Isolate* isolate) {
|
||||
bool Snapshot::Initialize() {
|
||||
if (size_ > 0) {
|
||||
base::ElapsedTimer timer;
|
||||
if (FLAG_profile_deserialization) {
|
||||
@ -35,7 +35,7 @@ bool Snapshot::Initialize(Isolate* isolate) {
|
||||
SnapshotByteSource source(raw_data_, raw_size_);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForLinkedInSnapshot(&deserializer);
|
||||
bool success = isolate->Init(&deserializer);
|
||||
bool success = V8::Initialize(&deserializer);
|
||||
if (FLAG_profile_deserialization) {
|
||||
double ms = timer.Elapsed().InMillisecondsF();
|
||||
PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
|
||||
|
@ -46,7 +46,7 @@ bool Snapshot::HaveASnapshotToStartFrom() {
|
||||
}
|
||||
|
||||
|
||||
bool Snapshot::Initialize(Isolate* isolate) {
|
||||
bool Snapshot::Initialize() {
|
||||
if (!HaveASnapshotToStartFrom())
|
||||
return false;
|
||||
|
||||
@ -66,7 +66,7 @@ bool Snapshot::Initialize(Isolate* isolate) {
|
||||
deserializer.set_reservation(CELL_SPACE, snapshot_impl_->cell_space_used);
|
||||
deserializer.set_reservation(PROPERTY_CELL_SPACE,
|
||||
snapshot_impl_->property_cell_space_used);
|
||||
bool success = isolate->Init(&deserializer);
|
||||
bool success = V8::Initialize(&deserializer);
|
||||
if (FLAG_profile_deserialization) {
|
||||
double ms = timer.Elapsed().InMillisecondsF();
|
||||
PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
|
||||
|
@ -12,9 +12,9 @@ namespace internal {
|
||||
|
||||
class Snapshot {
|
||||
public:
|
||||
// Initialize the Isolate from the internal snapshot. Returns false if no
|
||||
// snapshot could be found.
|
||||
static bool Initialize(Isolate* isolate);
|
||||
// Initialize the VM from the internal snapshot. Returns false if no snapshot
|
||||
// could be found.
|
||||
static bool Initialize();
|
||||
|
||||
static bool HaveASnapshotToStartFrom();
|
||||
|
||||
|
11
src/v8.cc
11
src/v8.cc
@ -33,9 +33,14 @@ v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
|
||||
v8::Platform* V8::platform_ = NULL;
|
||||
|
||||
|
||||
bool V8::Initialize() {
|
||||
bool V8::Initialize(Deserializer* des) {
|
||||
InitializeOncePerProcess();
|
||||
return true;
|
||||
Isolate* isolate = Isolate::UncheckedCurrent();
|
||||
if (isolate == NULL) return true;
|
||||
if (isolate->IsDead()) return false;
|
||||
if (isolate->IsInitialized()) return true;
|
||||
|
||||
return isolate->Init(des);
|
||||
}
|
||||
|
||||
|
||||
@ -74,8 +79,6 @@ void V8::InitializeOncePerProcessImpl() {
|
||||
|
||||
base::OS::Initialize(FLAG_random_seed, FLAG_hard_abort, FLAG_gc_fake_mmap);
|
||||
|
||||
Isolate::InitializeOncePerProcess();
|
||||
|
||||
Sampler::SetUp();
|
||||
CpuFeatures::Probe(false);
|
||||
init_memcopy_functions();
|
||||
|
8
src/v8.h
8
src/v8.h
@ -49,11 +49,17 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class Deserializer;
|
||||
|
||||
class V8 : public AllStatic {
|
||||
public:
|
||||
// Global actions.
|
||||
|
||||
static bool Initialize();
|
||||
// If Initialize is called with des == NULL, the initial state is
|
||||
// created from scratch. If a non-null Deserializer is given, the
|
||||
// initial state is created by reading the deserialized data into an
|
||||
// empty heap.
|
||||
static bool Initialize(Deserializer* des);
|
||||
static void TearDown();
|
||||
|
||||
// Report process out of memory. Implementation found in api.cc.
|
||||
|
@ -164,8 +164,8 @@ int main(int argc, char* argv[]) {
|
||||
v8::V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
|
||||
v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
v8::V8::Initialize();
|
||||
|
||||
CcTestArrayBufferAllocator array_buffer_allocator;
|
||||
v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
|
||||
@ -182,6 +182,10 @@ int main(int argc, char* argv[]) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
char* arg = argv[i];
|
||||
if (strcmp(arg, "--list") == 0) {
|
||||
// TODO(svenpanne) Serializer::enabled() and Serializer::code_address_map_
|
||||
// are fundamentally broken, so we can't unconditionally initialize and
|
||||
// dispose V8.
|
||||
v8::V8::Initialize();
|
||||
PrintTestList(CcTest::last());
|
||||
print_run_count = false;
|
||||
|
||||
|
@ -53,13 +53,6 @@
|
||||
static void Test##Name()
|
||||
#endif
|
||||
|
||||
#ifndef UNINITIALIZED_DEPENDENT_TEST
|
||||
#define UNINITIALIZED_DEPENDENT_TEST(Name, Dep) \
|
||||
static void Test##Name(); \
|
||||
CcTest register_test_##Name(Test##Name, __FILE__, #Name, #Dep, true, false); \
|
||||
static void Test##Name()
|
||||
#endif
|
||||
|
||||
#ifndef DISABLED_TEST
|
||||
#define DISABLED_TEST(Name) \
|
||||
static void Test##Name(); \
|
||||
|
@ -19486,26 +19486,31 @@ static int CalcFibonacci(v8::Isolate* isolate, int limit) {
|
||||
|
||||
class IsolateThread : public v8::base::Thread {
|
||||
public:
|
||||
explicit IsolateThread(int fib_limit)
|
||||
: Thread(Options("IsolateThread")), fib_limit_(fib_limit), result_(0) {}
|
||||
IsolateThread(v8::Isolate* isolate, int fib_limit)
|
||||
: Thread(Options("IsolateThread")),
|
||||
isolate_(isolate),
|
||||
fib_limit_(fib_limit),
|
||||
result_(0) {}
|
||||
|
||||
void Run() {
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
result_ = CalcFibonacci(isolate, fib_limit_);
|
||||
isolate->Dispose();
|
||||
result_ = CalcFibonacci(isolate_, fib_limit_);
|
||||
}
|
||||
|
||||
int result() { return result_; }
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
int fib_limit_;
|
||||
int result_;
|
||||
};
|
||||
|
||||
|
||||
TEST(MultipleIsolatesOnIndividualThreads) {
|
||||
IsolateThread thread1(21);
|
||||
IsolateThread thread2(12);
|
||||
v8::Isolate* isolate1 = v8::Isolate::New();
|
||||
v8::Isolate* isolate2 = v8::Isolate::New();
|
||||
|
||||
IsolateThread thread1(isolate1, 21);
|
||||
IsolateThread thread2(isolate2, 12);
|
||||
|
||||
// Compute some fibonacci numbers on 3 threads in 3 isolates.
|
||||
thread1.Start();
|
||||
@ -19523,6 +19528,9 @@ TEST(MultipleIsolatesOnIndividualThreads) {
|
||||
CHECK_EQ(result2, 144);
|
||||
CHECK_EQ(result1, thread1.result());
|
||||
CHECK_EQ(result2, thread2.result());
|
||||
|
||||
isolate1->Dispose();
|
||||
isolate2->Dispose();
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
using namespace v8::internal;
|
||||
|
||||
TEST(List) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
List<AstNode*>* list = new List<AstNode*>(0);
|
||||
CHECK_EQ(0, list->length());
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
using namespace v8::internal;
|
||||
|
||||
TEST(BitVector) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
Zone zone(CcTest::i_isolate());
|
||||
{
|
||||
BitVector v(15, &zone);
|
||||
|
@ -72,24 +72,17 @@ using ::v8::internal::StrLength;
|
||||
// Helper class for creating a V8 enviromnent for running tests
|
||||
class DebugLocalContext {
|
||||
public:
|
||||
inline DebugLocalContext(
|
||||
v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0,
|
||||
v8::Handle<v8::ObjectTemplate> global_template =
|
||||
v8::Handle<v8::ObjectTemplate>(),
|
||||
v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>())
|
||||
: scope_(isolate),
|
||||
context_(v8::Context::New(isolate, extensions, global_template,
|
||||
global_object)) {
|
||||
context_->Enter();
|
||||
}
|
||||
inline DebugLocalContext(
|
||||
v8::ExtensionConfiguration* extensions = 0,
|
||||
v8::Handle<v8::ObjectTemplate> global_template =
|
||||
v8::Handle<v8::ObjectTemplate>(),
|
||||
v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>())
|
||||
: scope_(CcTest::isolate()),
|
||||
context_(v8::Context::New(CcTest::isolate(), extensions,
|
||||
global_template, global_object)) {
|
||||
context_(
|
||||
v8::Context::New(CcTest::isolate(),
|
||||
extensions,
|
||||
global_template,
|
||||
global_object)) {
|
||||
context_->Enter();
|
||||
}
|
||||
inline ~DebugLocalContext() {
|
||||
@ -144,7 +137,8 @@ static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate,
|
||||
const char* source,
|
||||
const char* function_name) {
|
||||
v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run();
|
||||
v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global();
|
||||
v8::Local<v8::Object> global =
|
||||
CcTest::isolate()->GetCurrentContext()->Global();
|
||||
return v8::Local<v8::Function>::Cast(
|
||||
global->Get(v8::String::NewFromUtf8(isolate, function_name)));
|
||||
}
|
||||
@ -5161,20 +5155,12 @@ class V8Thread : public v8::base::Thread {
|
||||
public:
|
||||
V8Thread() : Thread(Options("V8Thread")) {}
|
||||
void Run();
|
||||
v8::Isolate* isolate() { return isolate_; }
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
};
|
||||
|
||||
class DebuggerThread : public v8::base::Thread {
|
||||
public:
|
||||
explicit DebuggerThread(v8::Isolate* isolate)
|
||||
: Thread(Options("DebuggerThread")), isolate_(isolate) {}
|
||||
DebuggerThread() : Thread(Options("DebuggerThread")) {}
|
||||
void Run();
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
};
|
||||
|
||||
|
||||
@ -5217,25 +5203,22 @@ void V8Thread::Run() {
|
||||
"\n"
|
||||
"foo();\n";
|
||||
|
||||
isolate_ = v8::Isolate::New();
|
||||
threaded_debugging_barriers.barrier_3.Wait();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
DebugLocalContext env(isolate_);
|
||||
v8::HandleScope scope(isolate_);
|
||||
v8::Debug::SetMessageHandler(&ThreadedMessageHandler);
|
||||
v8::Handle<v8::ObjectTemplate> global_template =
|
||||
v8::ObjectTemplate::New(env->GetIsolate());
|
||||
global_template->Set(
|
||||
v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"),
|
||||
v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1));
|
||||
v8::Handle<v8::Context> context =
|
||||
v8::Context::New(isolate_, NULL, global_template);
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
DebugLocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
v8::Debug::SetMessageHandler(&ThreadedMessageHandler);
|
||||
v8::Handle<v8::ObjectTemplate> global_template =
|
||||
v8::ObjectTemplate::New(env->GetIsolate());
|
||||
global_template->Set(
|
||||
v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"),
|
||||
v8::FunctionTemplate::New(isolate, ThreadedAtBarrier1));
|
||||
v8::Handle<v8::Context> context = v8::Context::New(isolate,
|
||||
NULL,
|
||||
global_template);
|
||||
v8::Context::Scope context_scope(context);
|
||||
|
||||
CompileRun(source);
|
||||
}
|
||||
isolate_->Dispose();
|
||||
CompileRun(source);
|
||||
}
|
||||
|
||||
|
||||
@ -5251,21 +5234,21 @@ void DebuggerThread::Run() {
|
||||
"\"type\":\"request\","
|
||||
"\"command\":\"continue\"}";
|
||||
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
threaded_debugging_barriers.barrier_1.Wait();
|
||||
v8::Debug::DebugBreak(isolate_);
|
||||
v8::Debug::DebugBreak(isolate);
|
||||
threaded_debugging_barriers.barrier_2.Wait();
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer));
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer));
|
||||
}
|
||||
|
||||
|
||||
TEST(ThreadedDebugging) {
|
||||
DebuggerThread debugger_thread;
|
||||
V8Thread v8_thread;
|
||||
|
||||
// Create a V8 environment
|
||||
v8_thread.Start();
|
||||
threaded_debugging_barriers.barrier_3.Wait();
|
||||
DebuggerThread debugger_thread(v8_thread.isolate());
|
||||
debugger_thread.Start();
|
||||
|
||||
v8_thread.Join();
|
||||
@ -5284,24 +5267,17 @@ class BreakpointsV8Thread : public v8::base::Thread {
|
||||
public:
|
||||
BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {}
|
||||
void Run();
|
||||
|
||||
v8::Isolate* isolate() { return isolate_; }
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
};
|
||||
|
||||
class BreakpointsDebuggerThread : public v8::base::Thread {
|
||||
public:
|
||||
BreakpointsDebuggerThread(bool global_evaluate, v8::Isolate* isolate)
|
||||
explicit BreakpointsDebuggerThread(bool global_evaluate)
|
||||
: Thread(Options("BreakpointsDebuggerThread")),
|
||||
global_evaluate_(global_evaluate),
|
||||
isolate_(isolate) {}
|
||||
global_evaluate_(global_evaluate) {}
|
||||
void Run();
|
||||
|
||||
private:
|
||||
bool global_evaluate_;
|
||||
v8::Isolate* isolate_;
|
||||
};
|
||||
|
||||
|
||||
@ -5346,20 +5322,16 @@ void BreakpointsV8Thread::Run() {
|
||||
const char* source_2 = "cat(17);\n"
|
||||
"cat(19);\n";
|
||||
|
||||
isolate_ = v8::Isolate::New();
|
||||
breakpoints_barriers->barrier_3.Wait();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
DebugLocalContext env(isolate_);
|
||||
v8::HandleScope scope(isolate_);
|
||||
v8::Debug::SetMessageHandler(&BreakpointsMessageHandler);
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
DebugLocalContext env;
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Debug::SetMessageHandler(&BreakpointsMessageHandler);
|
||||
|
||||
CompileRun(source_1);
|
||||
breakpoints_barriers->barrier_1.Wait();
|
||||
breakpoints_barriers->barrier_2.Wait();
|
||||
CompileRun(source_2);
|
||||
}
|
||||
isolate_->Dispose();
|
||||
CompileRun(source_1);
|
||||
breakpoints_barriers->barrier_1.Wait();
|
||||
breakpoints_barriers->barrier_2.Wait();
|
||||
CompileRun(source_2);
|
||||
}
|
||||
|
||||
|
||||
@ -5425,12 +5397,14 @@ void BreakpointsDebuggerThread::Run() {
|
||||
"\"command\":\"continue\"}";
|
||||
|
||||
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
// v8 thread initializes, runs source_1
|
||||
breakpoints_barriers->barrier_1.Wait();
|
||||
// 1:Set breakpoint in cat() (will get id 1).
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer));
|
||||
// 2:Set breakpoint in dog() (will get id 2).
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer));
|
||||
breakpoints_barriers->barrier_2.Wait();
|
||||
// V8 thread starts compiling source_2.
|
||||
// Automatic break happens, to run queued commands
|
||||
@ -5442,42 +5416,43 @@ void BreakpointsDebuggerThread::Run() {
|
||||
// Must have hit breakpoint #1.
|
||||
CHECK_EQ(1, break_event_breakpoint_id);
|
||||
// 4:Evaluate dog() (which has a breakpoint).
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_3, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_3, buffer));
|
||||
// V8 thread hits breakpoint in dog().
|
||||
breakpoints_barriers->semaphore_1.Wait(); // wait for break event
|
||||
// Must have hit breakpoint #2.
|
||||
CHECK_EQ(2, break_event_breakpoint_id);
|
||||
// 5:Evaluate (x + 1).
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_4, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_4, buffer));
|
||||
// Evaluate (x + 1) finishes.
|
||||
breakpoints_barriers->semaphore_1.Wait();
|
||||
// Must have result 108.
|
||||
CHECK_EQ(108, evaluate_int_result);
|
||||
// 6:Continue evaluation of dog().
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_5, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_5, buffer));
|
||||
// Evaluate dog() finishes.
|
||||
breakpoints_barriers->semaphore_1.Wait();
|
||||
// Must have result 107.
|
||||
CHECK_EQ(107, evaluate_int_result);
|
||||
// 7:Continue evaluation of source_2, finish cat(17), hit breakpoint
|
||||
// in cat(19).
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_6, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_6, buffer));
|
||||
// Message callback gets break event.
|
||||
breakpoints_barriers->semaphore_1.Wait(); // wait for break event
|
||||
// Must have hit breakpoint #1.
|
||||
CHECK_EQ(1, break_event_breakpoint_id);
|
||||
// 8: Evaluate dog() with breaks disabled.
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_7, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_7, buffer));
|
||||
// Evaluate dog() finishes.
|
||||
breakpoints_barriers->semaphore_1.Wait();
|
||||
// Must have result 116.
|
||||
CHECK_EQ(116, evaluate_int_result);
|
||||
// 9: Continue evaluation of source2, reach end.
|
||||
v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_8, buffer));
|
||||
v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_8, buffer));
|
||||
}
|
||||
|
||||
|
||||
void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
|
||||
BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate);
|
||||
BreakpointsV8Thread breakpoints_v8_thread;
|
||||
|
||||
// Create a V8 environment
|
||||
@ -5485,9 +5460,6 @@ void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
|
||||
breakpoints_barriers = &stack_allocated_breakpoints_barriers;
|
||||
|
||||
breakpoints_v8_thread.Start();
|
||||
breakpoints_barriers->barrier_3.Wait();
|
||||
BreakpointsDebuggerThread breakpoints_debugger_thread(
|
||||
global_evaluate, breakpoints_v8_thread.isolate());
|
||||
breakpoints_debugger_thread.Start();
|
||||
|
||||
breakpoints_v8_thread.Join();
|
||||
|
@ -98,8 +98,8 @@ class AllowNativesSyntaxNoInlining {
|
||||
|
||||
// Abort any ongoing incremental marking to make sure that all weak global
|
||||
// handle callbacks are processed.
|
||||
static void NonIncrementalGC(i::Isolate* isolate) {
|
||||
isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
|
||||
static void NonIncrementalGC() {
|
||||
CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ TEST(DeoptimizeSimple) {
|
||||
"function f() { g(); };"
|
||||
"f();");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
@ -143,7 +143,7 @@ TEST(DeoptimizeSimple) {
|
||||
"function f(x) { if (x) { g(); } else { return } };"
|
||||
"f(true);");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
@ -167,7 +167,7 @@ TEST(DeoptimizeSimpleWithArguments) {
|
||||
"function f(x, y, z) { g(1,x); y+z; };"
|
||||
"f(1, \"2\", false);");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
@ -184,7 +184,7 @@ TEST(DeoptimizeSimpleWithArguments) {
|
||||
"function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };"
|
||||
"f(true, 1, \"2\");");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
@ -209,7 +209,7 @@ TEST(DeoptimizeSimpleNested) {
|
||||
"function g(z) { count++; %DeoptimizeFunction(f); return z;}"
|
||||
"function f(x,y,z) { return h(x, y, g(z)); };"
|
||||
"result = f(1, 2, 3);");
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
@ -235,7 +235,7 @@ TEST(DeoptimizeRecursive) {
|
||||
"function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };"
|
||||
"f(10);");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value());
|
||||
@ -268,7 +268,7 @@ TEST(DeoptimizeMultiple) {
|
||||
"function f1(x) { return f2(x + 1, x + 1) + x; };"
|
||||
"result = f1(1);");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
@ -290,7 +290,7 @@ TEST(DeoptimizeConstructor) {
|
||||
"function f() { g(); };"
|
||||
"result = new f() instanceof f;");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK(env->Global()->Get(v8_str("result"))->IsTrue());
|
||||
@ -307,7 +307,7 @@ TEST(DeoptimizeConstructor) {
|
||||
"result = new f(1, 2);"
|
||||
"result = result.x + result.y;");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
@ -337,7 +337,7 @@ TEST(DeoptimizeConstructorMultiple) {
|
||||
"function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };"
|
||||
"result = new f1(1).result;");
|
||||
}
|
||||
NonIncrementalGC(CcTest::i_isolate());
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
@ -345,61 +345,51 @@ TEST(DeoptimizeConstructorMultiple) {
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) {
|
||||
TEST(DeoptimizeBinaryOperationADDString) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
const char* f_source = "function f(x, y) { return x + y; };";
|
||||
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
// Compile function f and collect to type feedback to insert binary op stub
|
||||
// call in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun("var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.toString = function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'"
|
||||
"};");
|
||||
CompileRun(f_source);
|
||||
CompileRun("for (var i = 0; i < 5; i++) {"
|
||||
" f('a+', new X());"
|
||||
"};");
|
||||
|
||||
const char* f_source = "function f(x, y) { return x + y; };";
|
||||
// Compile an optimized version of f.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f_source);
|
||||
CompileRun("f('a+', new X());");
|
||||
CHECK(!CcTest::i_isolate()->use_crankshaft() ||
|
||||
GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
|
||||
{
|
||||
// Compile function f and collect to type feedback to insert binary op
|
||||
// stub call in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun(
|
||||
"var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.toString = function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f); } return 'an X'"
|
||||
"};");
|
||||
CompileRun(f_source);
|
||||
CompileRun(
|
||||
"for (var i = 0; i < 5; i++) {"
|
||||
" f('a+', new X());"
|
||||
"};");
|
||||
|
||||
// Compile an optimized version of f.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f_source);
|
||||
CompileRun("f('a+', new X());");
|
||||
CHECK(!i_isolate->use_crankshaft() ||
|
||||
GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
|
||||
// Call f and force deoptimization while processing the binary operation.
|
||||
CompileRun(
|
||||
"deopt = true;"
|
||||
"var result = f('a+', new X());");
|
||||
}
|
||||
NonIncrementalGC(i_isolate);
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result"));
|
||||
CHECK(result->IsString());
|
||||
v8::String::Utf8Value utf8(result);
|
||||
CHECK_EQ("a+an X", *utf8);
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
// Call f and force deoptimization while processing the binary operation.
|
||||
CompileRun("deopt = true;"
|
||||
"var result = f('a+', new X());");
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result"));
|
||||
CHECK(result->IsString());
|
||||
v8::String::Utf8Value utf8(result);
|
||||
CHECK_EQ("a+an X", *utf8);
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
|
||||
@ -416,7 +406,6 @@ static void CompileConstructorWithDeoptimizingValueOf() {
|
||||
|
||||
static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
|
||||
const char* binary_op) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>((*env)->GetIsolate());
|
||||
EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> f_source_buffer;
|
||||
SNPrintF(f_source_buffer,
|
||||
"function f(x, y) { return x %s y; };",
|
||||
@ -437,355 +426,290 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f_source);
|
||||
CompileRun("f(7, new X());");
|
||||
CHECK(!i_isolate->use_crankshaft() ||
|
||||
CHECK(!CcTest::i_isolate()->use_crankshaft() ||
|
||||
GetJSFunction((*env)->Global(), "f")->IsOptimized());
|
||||
|
||||
// Call f and force deoptimization while processing the binary operation.
|
||||
CompileRun("deopt = true;"
|
||||
"var result = f(7, new X());");
|
||||
NonIncrementalGC(i_isolate);
|
||||
NonIncrementalGC();
|
||||
CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized());
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) {
|
||||
TEST(DeoptimizeBinaryOperationADD) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
TestDeoptimizeBinaryOpHelper(&env, "+");
|
||||
TestDeoptimizeBinaryOpHelper(&env, "+");
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) {
|
||||
TEST(DeoptimizeBinaryOperationSUB) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
TestDeoptimizeBinaryOpHelper(&env, "-");
|
||||
TestDeoptimizeBinaryOpHelper(&env, "-");
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) {
|
||||
TEST(DeoptimizeBinaryOperationMUL) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
TestDeoptimizeBinaryOpHelper(&env, "*");
|
||||
TestDeoptimizeBinaryOpHelper(&env, "*");
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) {
|
||||
TEST(DeoptimizeBinaryOperationDIV) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
TestDeoptimizeBinaryOpHelper(&env, "/");
|
||||
TestDeoptimizeBinaryOpHelper(&env, "/");
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
|
||||
TEST(DeoptimizeBinaryOperationMOD) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
TestDeoptimizeBinaryOpHelper(&env, "%");
|
||||
TestDeoptimizeBinaryOpHelper(&env, "%");
|
||||
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeCompare) {
|
||||
TEST(DeoptimizeCompare) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
const char* f_source = "function f(x, y) { return x < y; };";
|
||||
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
// Compile function f and collect to type feedback to insert compare ic
|
||||
// call in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun("var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.toString = function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'"
|
||||
"};");
|
||||
CompileRun(f_source);
|
||||
CompileRun("for (var i = 0; i < 5; i++) {"
|
||||
" f('a', new X());"
|
||||
"};");
|
||||
|
||||
const char* f_source = "function f(x, y) { return x < y; };";
|
||||
// Compile an optimized version of f.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f_source);
|
||||
CompileRun("f('a', new X());");
|
||||
CHECK(!CcTest::i_isolate()->use_crankshaft() ||
|
||||
GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
|
||||
{
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
// Compile function f and collect to type feedback to insert compare ic
|
||||
// call in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun(
|
||||
"var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.toString = function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f); } return 'b'"
|
||||
"};");
|
||||
CompileRun(f_source);
|
||||
CompileRun(
|
||||
"for (var i = 0; i < 5; i++) {"
|
||||
" f('a', new X());"
|
||||
"};");
|
||||
// Call f and force deoptimization while processing the comparison.
|
||||
CompileRun("deopt = true;"
|
||||
"var result = f('a', new X());");
|
||||
}
|
||||
NonIncrementalGC();
|
||||
|
||||
// Compile an optimized version of f.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f_source);
|
||||
CompileRun("f('a', new X());");
|
||||
CHECK(!i_isolate->use_crankshaft() ||
|
||||
GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate()));
|
||||
}
|
||||
|
||||
// Call f and force deoptimization while processing the comparison.
|
||||
CompileRun(
|
||||
"deopt = true;"
|
||||
"var result = f('a', new X());");
|
||||
|
||||
TEST(DeoptimizeLoadICStoreIC) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
// Functions to generate load/store/keyed load/keyed store IC calls.
|
||||
const char* f1_source = "function f1(x) { return x.y; };";
|
||||
const char* g1_source = "function g1(x) { x.y = 1; };";
|
||||
const char* f2_source = "function f2(x, y) { return x[y]; };";
|
||||
const char* g2_source = "function g2(x, y) { x[y] = 1; };";
|
||||
|
||||
{
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
// Compile functions and collect to type feedback to insert ic
|
||||
// calls in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun("var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.__defineGetter__('y', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f1); };"
|
||||
" return 13;"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('y', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(g1); };"
|
||||
"});"
|
||||
"X.prototype.__defineGetter__('z', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f2); };"
|
||||
" return 13;"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('z', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(g2); };"
|
||||
"});");
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun("for (var i = 0; i < 5; i++) {"
|
||||
" f1(new X());"
|
||||
" g1(new X());"
|
||||
" f2(new X(), 'z');"
|
||||
" g2(new X(), 'z');"
|
||||
"};");
|
||||
|
||||
// Compile an optimized version of the functions.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun("f1(new X());");
|
||||
CompileRun("g1(new X());");
|
||||
CompileRun("f2(new X(), 'z');");
|
||||
CompileRun("g2(new X(), 'z');");
|
||||
if (CcTest::i_isolate()->use_crankshaft()) {
|
||||
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
}
|
||||
NonIncrementalGC(i_isolate);
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue());
|
||||
CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate));
|
||||
// Call functions and force deoptimization while processing the ics.
|
||||
CompileRun("deopt = true;"
|
||||
"var result = f1(new X());"
|
||||
"g1(new X());"
|
||||
"f2(new X(), 'z');"
|
||||
"g2(new X(), 'z');");
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
|
||||
TEST(DeoptimizeLoadICStoreICNested) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
// Functions to generate load/store/keyed load/keyed store IC calls.
|
||||
const char* f1_source = "function f1(x) { return x.y; };";
|
||||
const char* g1_source = "function g1(x) { x.y = 1; };";
|
||||
const char* f2_source = "function f2(x, y) { return x[y]; };";
|
||||
const char* g2_source = "function g2(x, y) { x[y] = 1; };";
|
||||
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
// Compile functions and collect to type feedback to insert ic
|
||||
// calls in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun("var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.__defineGetter__('y', function () {"
|
||||
" g1(this);"
|
||||
" return 13;"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('y', function () {"
|
||||
" f2(this, 'z');"
|
||||
"});"
|
||||
"X.prototype.__defineGetter__('z', function () {"
|
||||
" g2(this, 'z');"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('z', function () {"
|
||||
" if (deopt) {"
|
||||
" count++;"
|
||||
" %DeoptimizeFunction(f1);"
|
||||
" %DeoptimizeFunction(g1);"
|
||||
" %DeoptimizeFunction(f2);"
|
||||
" %DeoptimizeFunction(g2); };"
|
||||
"});");
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun("for (var i = 0; i < 5; i++) {"
|
||||
" f1(new X());"
|
||||
" g1(new X());"
|
||||
" f2(new X(), 'z');"
|
||||
" g2(new X(), 'z');"
|
||||
"};");
|
||||
|
||||
// Functions to generate load/store/keyed load/keyed store IC calls.
|
||||
const char* f1_source = "function f1(x) { return x.y; };";
|
||||
const char* g1_source = "function g1(x) { x.y = 1; };";
|
||||
const char* f2_source = "function f2(x, y) { return x[y]; };";
|
||||
const char* g2_source = "function g2(x, y) { x[y] = 1; };";
|
||||
|
||||
{
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
// Compile functions and collect to type feedback to insert ic
|
||||
// calls in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun(
|
||||
"var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.__defineGetter__('y', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f1); };"
|
||||
" return 13;"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('y', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(g1); };"
|
||||
"});"
|
||||
"X.prototype.__defineGetter__('z', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(f2); };"
|
||||
" return 13;"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('z', function () {"
|
||||
" if (deopt) { count++; %DeoptimizeFunction(g2); };"
|
||||
"});");
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun(
|
||||
"for (var i = 0; i < 5; i++) {"
|
||||
" f1(new X());"
|
||||
" g1(new X());"
|
||||
" f2(new X(), 'z');"
|
||||
" g2(new X(), 'z');"
|
||||
"};");
|
||||
|
||||
// Compile an optimized version of the functions.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun("f1(new X());");
|
||||
CompileRun("g1(new X());");
|
||||
CompileRun("f2(new X(), 'z');");
|
||||
CompileRun("g2(new X(), 'z');");
|
||||
if (i_isolate->use_crankshaft()) {
|
||||
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
}
|
||||
|
||||
// Call functions and force deoptimization while processing the ics.
|
||||
CompileRun(
|
||||
"deopt = true;"
|
||||
"var result = f1(new X());"
|
||||
"g1(new X());"
|
||||
"f2(new X(), 'z');"
|
||||
"g2(new X(), 'z');");
|
||||
// Compile an optimized version of the functions.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun("f1(new X());");
|
||||
CompileRun("g1(new X());");
|
||||
CompileRun("f2(new X(), 'z');");
|
||||
CompileRun("g2(new X(), 'z');");
|
||||
if (CcTest::i_isolate()->use_crankshaft()) {
|
||||
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
}
|
||||
NonIncrementalGC(i_isolate);
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
// Call functions and force deoptimization while processing the ics.
|
||||
CompileRun("deopt = true;"
|
||||
"var result = f1(new X());");
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) {
|
||||
i::FLAG_turbo_deoptimization = true;
|
||||
i::FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
{
|
||||
LocalContext env(isolate);
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
||||
// Functions to generate load/store/keyed load/keyed store IC calls.
|
||||
const char* f1_source = "function f1(x) { return x.y; };";
|
||||
const char* g1_source = "function g1(x) { x.y = 1; };";
|
||||
const char* f2_source = "function f2(x, y) { return x[y]; };";
|
||||
const char* g2_source = "function g2(x, y) { x[y] = 1; };";
|
||||
|
||||
{
|
||||
AllowNativesSyntaxNoInlining options;
|
||||
// Compile functions and collect to type feedback to insert ic
|
||||
// calls in the optimized code.
|
||||
i::FLAG_prepare_always_opt = true;
|
||||
CompileRun(
|
||||
"var count = 0;"
|
||||
"var result = 0;"
|
||||
"var deopt = false;"
|
||||
"function X() { };"
|
||||
"X.prototype.__defineGetter__('y', function () {"
|
||||
" g1(this);"
|
||||
" return 13;"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('y', function () {"
|
||||
" f2(this, 'z');"
|
||||
"});"
|
||||
"X.prototype.__defineGetter__('z', function () {"
|
||||
" g2(this, 'z');"
|
||||
"});"
|
||||
"X.prototype.__defineSetter__('z', function () {"
|
||||
" if (deopt) {"
|
||||
" count++;"
|
||||
" %DeoptimizeFunction(f1);"
|
||||
" %DeoptimizeFunction(g1);"
|
||||
" %DeoptimizeFunction(f2);"
|
||||
" %DeoptimizeFunction(g2); };"
|
||||
"});");
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun(
|
||||
"for (var i = 0; i < 5; i++) {"
|
||||
" f1(new X());"
|
||||
" g1(new X());"
|
||||
" f2(new X(), 'z');"
|
||||
" g2(new X(), 'z');"
|
||||
"};");
|
||||
|
||||
// Compile an optimized version of the functions.
|
||||
i::FLAG_always_opt = true;
|
||||
CompileRun(f1_source);
|
||||
CompileRun(g1_source);
|
||||
CompileRun(f2_source);
|
||||
CompileRun(g2_source);
|
||||
CompileRun("f1(new X());");
|
||||
CompileRun("g1(new X());");
|
||||
CompileRun("f2(new X(), 'z');");
|
||||
CompileRun("g2(new X(), 'z');");
|
||||
if (i_isolate->use_crankshaft()) {
|
||||
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
}
|
||||
|
||||
// Call functions and force deoptimization while processing the ics.
|
||||
CompileRun(
|
||||
"deopt = true;"
|
||||
"var result = f1(new X());");
|
||||
}
|
||||
NonIncrementalGC(i_isolate);
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
NonIncrementalGC();
|
||||
|
||||
CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized());
|
||||
CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized());
|
||||
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
|
||||
CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value());
|
||||
}
|
||||
|
@ -1052,61 +1052,53 @@ TEST(Regression39128) {
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(TestCodeFlushing) {
|
||||
TEST(TestCodeFlushing) {
|
||||
// If we do not flush code this test is invalid.
|
||||
if (!FLAG_flush_code) return;
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
i::FLAG_optimize_for_size = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
isolate->Enter();
|
||||
Factory* factory = i_isolate->factory();
|
||||
{
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Context::New(isolate)->Enter();
|
||||
const char* source =
|
||||
"function foo() {"
|
||||
" var x = 42;"
|
||||
" var y = 42;"
|
||||
" var z = x + y;"
|
||||
"};"
|
||||
"foo()";
|
||||
Handle<String> foo_name = factory->InternalizeUtf8String("foo");
|
||||
CcTest::InitializeVM();
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Factory* factory = isolate->factory();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
const char* source = "function foo() {"
|
||||
" var x = 42;"
|
||||
" var y = 42;"
|
||||
" var z = x + y;"
|
||||
"};"
|
||||
"foo()";
|
||||
Handle<String> foo_name = factory->InternalizeUtf8String("foo");
|
||||
|
||||
// This compile will add the code to the compilation cache.
|
||||
{
|
||||
v8::HandleScope scope(isolate);
|
||||
CompileRun(source);
|
||||
}
|
||||
|
||||
// Check function is compiled.
|
||||
Handle<Object> func_value = Object::GetProperty(i_isolate->global_object(),
|
||||
foo_name).ToHandleChecked();
|
||||
CHECK(func_value->IsJSFunction());
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(func_value);
|
||||
CHECK(function->shared()->is_compiled());
|
||||
|
||||
// The code will survive at least two GCs.
|
||||
i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||
i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||
CHECK(function->shared()->is_compiled());
|
||||
|
||||
// Simulate several GCs that use full marking.
|
||||
const int kAgingThreshold = 6;
|
||||
for (int i = 0; i < kAgingThreshold; i++) {
|
||||
i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||
}
|
||||
|
||||
// foo should no longer be in the compilation cache
|
||||
CHECK(!function->shared()->is_compiled() || function->IsOptimized());
|
||||
CHECK(!function->is_compiled() || function->IsOptimized());
|
||||
// Call foo to get it recompiled.
|
||||
CompileRun("foo()");
|
||||
CHECK(function->shared()->is_compiled());
|
||||
CHECK(function->is_compiled());
|
||||
// This compile will add the code to the compilation cache.
|
||||
{ v8::HandleScope scope(CcTest::isolate());
|
||||
CompileRun(source);
|
||||
}
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
|
||||
// Check function is compiled.
|
||||
Handle<Object> func_value = Object::GetProperty(
|
||||
CcTest::i_isolate()->global_object(), foo_name).ToHandleChecked();
|
||||
CHECK(func_value->IsJSFunction());
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(func_value);
|
||||
CHECK(function->shared()->is_compiled());
|
||||
|
||||
// The code will survive at least two GCs.
|
||||
CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||
CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||
CHECK(function->shared()->is_compiled());
|
||||
|
||||
// Simulate several GCs that use full marking.
|
||||
const int kAgingThreshold = 6;
|
||||
for (int i = 0; i < kAgingThreshold; i++) {
|
||||
CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
|
||||
}
|
||||
|
||||
// foo should no longer be in the compilation cache
|
||||
CHECK(!function->shared()->is_compiled() || function->IsOptimized());
|
||||
CHECK(!function->is_compiled() || function->IsOptimized());
|
||||
// Call foo to get it recompiled.
|
||||
CompileRun("foo()");
|
||||
CHECK(function->shared()->is_compiled());
|
||||
CHECK(function->is_compiled());
|
||||
}
|
||||
|
||||
|
||||
@ -3305,28 +3297,26 @@ class SourceResource : public v8::String::ExternalOneByteStringResource {
|
||||
};
|
||||
|
||||
|
||||
void ReleaseStackTraceDataTest(v8::Isolate* isolate, const char* source,
|
||||
const char* accessor) {
|
||||
void ReleaseStackTraceDataTest(const char* source, const char* accessor) {
|
||||
// Test that the data retained by the Error.stack accessor is released
|
||||
// after the first time the accessor is fired. We use external string
|
||||
// to check whether the data is being released since the external string
|
||||
// resource's callback is fired when the external string is GC'ed.
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
SourceResource* resource = new SourceResource(i::StrDup(source));
|
||||
{
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Handle<v8::String> source_string =
|
||||
v8::String::NewExternal(isolate, resource);
|
||||
i_isolate->heap()->CollectAllAvailableGarbage();
|
||||
v8::String::NewExternal(CcTest::isolate(), resource);
|
||||
CcTest::heap()->CollectAllAvailableGarbage();
|
||||
v8::Script::Compile(source_string)->Run();
|
||||
CHECK(!resource->IsDisposed());
|
||||
}
|
||||
// i_isolate->heap()->CollectAllAvailableGarbage();
|
||||
// CcTest::heap()->CollectAllAvailableGarbage();
|
||||
CHECK(!resource->IsDisposed());
|
||||
|
||||
CompileRun(accessor);
|
||||
i_isolate->heap()->CollectAllAvailableGarbage();
|
||||
CcTest::heap()->CollectAllAvailableGarbage();
|
||||
|
||||
// External source has been released.
|
||||
CHECK(resource->IsDisposed());
|
||||
@ -3334,7 +3324,7 @@ void ReleaseStackTraceDataTest(v8::Isolate* isolate, const char* source,
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(ReleaseStackTraceData) {
|
||||
TEST(ReleaseStackTraceData) {
|
||||
if (i::FLAG_always_opt) {
|
||||
// TODO(ulan): Remove this once the memory leak via code_next_link is fixed.
|
||||
// See: https://codereview.chromium.org/181833004/
|
||||
@ -3342,51 +3332,46 @@ UNINITIALIZED_TEST(ReleaseStackTraceData) {
|
||||
}
|
||||
FLAG_use_ic = false; // ICs retain objects.
|
||||
FLAG_concurrent_recompilation = false;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::New(isolate)->Enter();
|
||||
static const char* source1 = "var error = null; "
|
||||
/* Normal Error */ "try { "
|
||||
" throw new Error(); "
|
||||
"} catch (e) { "
|
||||
" error = e; "
|
||||
"} ";
|
||||
static const char* source2 = "var error = null; "
|
||||
/* Stack overflow */ "try { "
|
||||
" (function f() { f(); })(); "
|
||||
"} catch (e) { "
|
||||
" error = e; "
|
||||
"} ";
|
||||
static const char* source3 = "var error = null; "
|
||||
/* Normal Error */ "try { "
|
||||
/* as prototype */ " throw new Error(); "
|
||||
"} catch (e) { "
|
||||
" error = {}; "
|
||||
" error.__proto__ = e; "
|
||||
"} ";
|
||||
static const char* source4 = "var error = null; "
|
||||
/* Stack overflow */ "try { "
|
||||
/* as prototype */ " (function f() { f(); })(); "
|
||||
"} catch (e) { "
|
||||
" error = {}; "
|
||||
" error.__proto__ = e; "
|
||||
"} ";
|
||||
static const char* getter = "error.stack";
|
||||
static const char* setter = "error.stack = 0";
|
||||
CcTest::InitializeVM();
|
||||
static const char* source1 = "var error = null; "
|
||||
/* Normal Error */ "try { "
|
||||
" throw new Error(); "
|
||||
"} catch (e) { "
|
||||
" error = e; "
|
||||
"} ";
|
||||
static const char* source2 = "var error = null; "
|
||||
/* Stack overflow */ "try { "
|
||||
" (function f() { f(); })(); "
|
||||
"} catch (e) { "
|
||||
" error = e; "
|
||||
"} ";
|
||||
static const char* source3 = "var error = null; "
|
||||
/* Normal Error */ "try { "
|
||||
/* as prototype */ " throw new Error(); "
|
||||
"} catch (e) { "
|
||||
" error = {}; "
|
||||
" error.__proto__ = e; "
|
||||
"} ";
|
||||
static const char* source4 = "var error = null; "
|
||||
/* Stack overflow */ "try { "
|
||||
/* as prototype */ " (function f() { f(); })(); "
|
||||
"} catch (e) { "
|
||||
" error = {}; "
|
||||
" error.__proto__ = e; "
|
||||
"} ";
|
||||
static const char* getter = "error.stack";
|
||||
static const char* setter = "error.stack = 0";
|
||||
|
||||
ReleaseStackTraceDataTest(isolate, source1, setter);
|
||||
ReleaseStackTraceDataTest(isolate, source2, setter);
|
||||
// We do not test source3 and source4 with setter, since the setter is
|
||||
// supposed to (untypically) write to the receiver, not the holder. This is
|
||||
// to emulate the behavior of a data property.
|
||||
ReleaseStackTraceDataTest(source1, setter);
|
||||
ReleaseStackTraceDataTest(source2, setter);
|
||||
// We do not test source3 and source4 with setter, since the setter is
|
||||
// supposed to (untypically) write to the receiver, not the holder. This is
|
||||
// to emulate the behavior of a data property.
|
||||
|
||||
ReleaseStackTraceDataTest(isolate, source1, getter);
|
||||
ReleaseStackTraceDataTest(isolate, source2, getter);
|
||||
ReleaseStackTraceDataTest(isolate, source3, getter);
|
||||
ReleaseStackTraceDataTest(isolate, source4, getter);
|
||||
}
|
||||
ReleaseStackTraceDataTest(source1, getter);
|
||||
ReleaseStackTraceDataTest(source2, getter);
|
||||
ReleaseStackTraceDataTest(source3, getter);
|
||||
ReleaseStackTraceDataTest(source4, getter);
|
||||
}
|
||||
|
||||
|
||||
@ -4364,84 +4349,78 @@ TEST(ArrayShiftSweeping) {
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(PromotionQueue) {
|
||||
TEST(PromotionQueue) {
|
||||
i::FLAG_expose_gc = true;
|
||||
i::FLAG_max_semi_space_size = 2;
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Context::New(isolate)->Enter();
|
||||
Heap* heap = i_isolate->heap();
|
||||
NewSpace* new_space = heap->new_space();
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Heap* heap = isolate->heap();
|
||||
NewSpace* new_space = heap->new_space();
|
||||
|
||||
// In this test we will try to overwrite the promotion queue which is at the
|
||||
// end of to-space. To actually make that possible, we need at least two
|
||||
// semi-space pages and take advantage of fragementation.
|
||||
// (1) Grow semi-space to two pages.
|
||||
// (2) Create a few small long living objects and call the scavenger to
|
||||
// move them to the other semi-space.
|
||||
// (3) Create a huge object, i.e., remainder of first semi-space page and
|
||||
// create another huge object which should be of maximum allocatable memory
|
||||
// size of the second semi-space page.
|
||||
// (4) Call the scavenger again.
|
||||
// What will happen is: the scavenger will promote the objects created in
|
||||
// (2) and will create promotion queue entries at the end of the second
|
||||
// semi-space page during the next scavenge when it promotes the objects to
|
||||
// the old generation. The first allocation of (3) will fill up the first
|
||||
// semi-space page. The second allocation in (3) will not fit into the
|
||||
// first semi-space page, but it will overwrite the promotion queue which
|
||||
// are in the second semi-space page. If the right guards are in place, the
|
||||
// promotion queue will be evacuated in that case.
|
||||
// In this test we will try to overwrite the promotion queue which is at the
|
||||
// end of to-space. To actually make that possible, we need at least two
|
||||
// semi-space pages and take advantage of fragementation.
|
||||
// (1) Grow semi-space to two pages.
|
||||
// (2) Create a few small long living objects and call the scavenger to
|
||||
// move them to the other semi-space.
|
||||
// (3) Create a huge object, i.e., remainder of first semi-space page and
|
||||
// create another huge object which should be of maximum allocatable memory
|
||||
// size of the second semi-space page.
|
||||
// (4) Call the scavenger again.
|
||||
// What will happen is: the scavenger will promote the objects created in (2)
|
||||
// and will create promotion queue entries at the end of the second
|
||||
// semi-space page during the next scavenge when it promotes the objects to
|
||||
// the old generation. The first allocation of (3) will fill up the first
|
||||
// semi-space page. The second allocation in (3) will not fit into the first
|
||||
// semi-space page, but it will overwrite the promotion queue which are in
|
||||
// the second semi-space page. If the right guards are in place, the promotion
|
||||
// queue will be evacuated in that case.
|
||||
|
||||
// Grow the semi-space to two pages to make semi-space copy overwrite the
|
||||
// promotion queue, which will be at the end of the second page.
|
||||
intptr_t old_capacity = new_space->TotalCapacity();
|
||||
new_space->Grow();
|
||||
CHECK(new_space->IsAtMaximumCapacity());
|
||||
CHECK(2 * old_capacity == new_space->TotalCapacity());
|
||||
// Grow the semi-space to two pages to make semi-space copy overwrite the
|
||||
// promotion queue, which will be at the end of the second page.
|
||||
intptr_t old_capacity = new_space->TotalCapacity();
|
||||
new_space->Grow();
|
||||
CHECK(new_space->IsAtMaximumCapacity());
|
||||
CHECK(2 * old_capacity == new_space->TotalCapacity());
|
||||
|
||||
// Call the scavenger two times to get an empty new space
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
// Call the scavenger two times to get an empty new space
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
|
||||
// First create a few objects which will survive a scavenge, and will get
|
||||
// promoted to the old generation later on. These objects will create
|
||||
// promotion queue entries at the end of the second semi-space page.
|
||||
const int number_handles = 12;
|
||||
Handle<FixedArray> handles[number_handles];
|
||||
for (int i = 0; i < number_handles; i++) {
|
||||
handles[i] = i_isolate->factory()->NewFixedArray(1, NOT_TENURED);
|
||||
}
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
|
||||
// Create the first huge object which will exactly fit the first semi-space
|
||||
// page.
|
||||
int new_linear_size =
|
||||
static_cast<int>(*heap->new_space()->allocation_limit_address() -
|
||||
*heap->new_space()->allocation_top_address());
|
||||
int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize;
|
||||
Handle<FixedArray> first =
|
||||
i_isolate->factory()->NewFixedArray(length, NOT_TENURED);
|
||||
CHECK(heap->InNewSpace(*first));
|
||||
|
||||
// Create the second huge object of maximum allocatable second semi-space
|
||||
// page size.
|
||||
new_linear_size =
|
||||
static_cast<int>(*heap->new_space()->allocation_limit_address() -
|
||||
*heap->new_space()->allocation_top_address());
|
||||
length = Page::kMaxRegularHeapObjectSize / kPointerSize -
|
||||
FixedArray::kHeaderSize;
|
||||
Handle<FixedArray> second =
|
||||
i_isolate->factory()->NewFixedArray(length, NOT_TENURED);
|
||||
CHECK(heap->InNewSpace(*second));
|
||||
|
||||
// This scavenge will corrupt memory if the promotion queue is not
|
||||
// evacuated.
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
// First create a few objects which will survive a scavenge, and will get
|
||||
// promoted to the old generation later on. These objects will create
|
||||
// promotion queue entries at the end of the second semi-space page.
|
||||
const int number_handles = 12;
|
||||
Handle<FixedArray> handles[number_handles];
|
||||
for (int i = 0; i < number_handles; i++) {
|
||||
handles[i] = isolate->factory()->NewFixedArray(1, NOT_TENURED);
|
||||
}
|
||||
isolate->Dispose();
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
|
||||
// Create the first huge object which will exactly fit the first semi-space
|
||||
// page.
|
||||
int new_linear_size = static_cast<int>(
|
||||
*heap->new_space()->allocation_limit_address() -
|
||||
*heap->new_space()->allocation_top_address());
|
||||
int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize;
|
||||
Handle<FixedArray> first =
|
||||
isolate->factory()->NewFixedArray(length, NOT_TENURED);
|
||||
CHECK(heap->InNewSpace(*first));
|
||||
|
||||
// Create the second huge object of maximum allocatable second semi-space
|
||||
// page size.
|
||||
new_linear_size = static_cast<int>(
|
||||
*heap->new_space()->allocation_limit_address() -
|
||||
*heap->new_space()->allocation_top_address());
|
||||
length = Page::kMaxRegularHeapObjectSize / kPointerSize -
|
||||
FixedArray::kHeaderSize;
|
||||
Handle<FixedArray> second =
|
||||
isolate->factory()->NewFixedArray(length, NOT_TENURED);
|
||||
CHECK(heap->InNewSpace(*second));
|
||||
|
||||
// This scavenge will corrupt memory if the promotion queue is not evacuated.
|
||||
heap->CollectGarbage(NEW_SPACE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,6 +158,7 @@ void CompareStrings(const char* s1, const char* s2,
|
||||
// --- T h e A c t u a l T e s t s
|
||||
|
||||
TEST(LiveEditDiffer) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
CompareStrings("zz1zzz12zz123zzz", "zzzzzzzzzz", 6);
|
||||
CompareStrings("zz1zzz12zz123zzz", "zz0zzz0zz0zzz", 9);
|
||||
CompareStrings("123456789", "987654321", 16);
|
||||
|
@ -61,11 +61,9 @@ class ScopedLoggerInitializer {
|
||||
temp_file_(NULL),
|
||||
// Need to run this prior to creating the scope.
|
||||
trick_to_run_init_flags_(init_flags_()),
|
||||
isolate_(v8::Isolate::New()),
|
||||
isolate_scope_(isolate_),
|
||||
scope_(isolate_),
|
||||
env_(v8::Context::New(isolate_)),
|
||||
logger_(reinterpret_cast<i::Isolate*>(isolate_)->logger()) {
|
||||
scope_(CcTest::isolate()),
|
||||
env_(v8::Context::New(CcTest::isolate())),
|
||||
logger_(CcTest::i_isolate()->logger()) {
|
||||
env_->Enter();
|
||||
}
|
||||
|
||||
@ -79,8 +77,6 @@ class ScopedLoggerInitializer {
|
||||
|
||||
v8::Handle<v8::Context>& env() { return env_; }
|
||||
|
||||
v8::Isolate* isolate() { return isolate_; }
|
||||
|
||||
Logger* logger() { return logger_; }
|
||||
|
||||
FILE* StopLoggingGetTempFile() {
|
||||
@ -104,8 +100,6 @@ class ScopedLoggerInitializer {
|
||||
const bool saved_prof_;
|
||||
FILE* temp_file_;
|
||||
const bool trick_to_run_init_flags_;
|
||||
v8::Isolate* isolate_;
|
||||
v8::Isolate::Scope isolate_scope_;
|
||||
v8::HandleScope scope_;
|
||||
v8::Handle<v8::Context> env_;
|
||||
Logger* logger_;
|
||||
@ -336,41 +330,41 @@ static void ObjMethod1(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
|
||||
TEST(LogCallbacks) {
|
||||
v8::Isolate* isolate;
|
||||
{
|
||||
ScopedLoggerInitializer initialize_logger;
|
||||
isolate = initialize_logger.isolate();
|
||||
Logger* logger = initialize_logger.logger();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
ScopedLoggerInitializer initialize_logger;
|
||||
Logger* logger = initialize_logger.logger();
|
||||
|
||||
v8::Local<v8::FunctionTemplate> obj = v8::Local<v8::FunctionTemplate>::New(
|
||||
isolate, v8::FunctionTemplate::New(isolate));
|
||||
obj->SetClassName(v8_str("Obj"));
|
||||
v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate();
|
||||
v8::Local<v8::Signature> signature = v8::Signature::New(isolate, obj);
|
||||
proto->Set(v8_str("method1"),
|
||||
v8::FunctionTemplate::New(isolate, ObjMethod1,
|
||||
v8::Handle<v8::Value>(), signature),
|
||||
static_cast<v8::PropertyAttribute>(v8::DontDelete));
|
||||
v8::Local<v8::FunctionTemplate> obj =
|
||||
v8::Local<v8::FunctionTemplate>::New(isolate,
|
||||
v8::FunctionTemplate::New(isolate));
|
||||
obj->SetClassName(v8_str("Obj"));
|
||||
v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate();
|
||||
v8::Local<v8::Signature> signature =
|
||||
v8::Signature::New(isolate, obj);
|
||||
proto->Set(v8_str("method1"),
|
||||
v8::FunctionTemplate::New(isolate,
|
||||
ObjMethod1,
|
||||
v8::Handle<v8::Value>(),
|
||||
signature),
|
||||
static_cast<v8::PropertyAttribute>(v8::DontDelete));
|
||||
|
||||
initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
|
||||
CompileRun("Obj.prototype.method1.toString();");
|
||||
initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
|
||||
CompileRun("Obj.prototype.method1.toString();");
|
||||
|
||||
logger->LogCompiledFunctions();
|
||||
logger->LogCompiledFunctions();
|
||||
|
||||
bool exists = false;
|
||||
i::Vector<const char> log(
|
||||
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
|
||||
CHECK(exists);
|
||||
bool exists = false;
|
||||
i::Vector<const char> log(
|
||||
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
|
||||
CHECK(exists);
|
||||
|
||||
i::EmbeddedVector<char, 100> ref_data;
|
||||
i::SNPrintF(ref_data,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"",
|
||||
reinterpret_cast<intptr_t>(ObjMethod1));
|
||||
i::EmbeddedVector<char, 100> ref_data;
|
||||
i::SNPrintF(ref_data,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"method1\"",
|
||||
reinterpret_cast<intptr_t>(ObjMethod1));
|
||||
|
||||
CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
|
||||
log.Dispose();
|
||||
}
|
||||
isolate->Dispose();
|
||||
CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
|
||||
log.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -389,49 +383,46 @@ static void Prop2Getter(v8::Local<v8::String> property,
|
||||
|
||||
|
||||
TEST(LogAccessorCallbacks) {
|
||||
v8::Isolate* isolate;
|
||||
{
|
||||
ScopedLoggerInitializer initialize_logger;
|
||||
isolate = initialize_logger.isolate();
|
||||
Logger* logger = initialize_logger.logger();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
ScopedLoggerInitializer initialize_logger;
|
||||
Logger* logger = initialize_logger.logger();
|
||||
|
||||
v8::Local<v8::FunctionTemplate> obj = v8::Local<v8::FunctionTemplate>::New(
|
||||
isolate, v8::FunctionTemplate::New(isolate));
|
||||
obj->SetClassName(v8_str("Obj"));
|
||||
v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate();
|
||||
inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter);
|
||||
inst->SetAccessor(v8_str("prop2"), Prop2Getter);
|
||||
v8::Local<v8::FunctionTemplate> obj =
|
||||
v8::Local<v8::FunctionTemplate>::New(isolate,
|
||||
v8::FunctionTemplate::New(isolate));
|
||||
obj->SetClassName(v8_str("Obj"));
|
||||
v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate();
|
||||
inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter);
|
||||
inst->SetAccessor(v8_str("prop2"), Prop2Getter);
|
||||
|
||||
logger->LogAccessorCallbacks();
|
||||
logger->LogAccessorCallbacks();
|
||||
|
||||
bool exists = false;
|
||||
i::Vector<const char> log(
|
||||
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
|
||||
CHECK(exists);
|
||||
bool exists = false;
|
||||
i::Vector<const char> log(
|
||||
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
|
||||
CHECK(exists);
|
||||
|
||||
EmbeddedVector<char, 100> prop1_getter_record;
|
||||
i::SNPrintF(prop1_getter_record,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"",
|
||||
reinterpret_cast<intptr_t>(Prop1Getter));
|
||||
CHECK_NE(NULL,
|
||||
StrNStr(log.start(), prop1_getter_record.start(), log.length()));
|
||||
EmbeddedVector<char, 100> prop1_getter_record;
|
||||
i::SNPrintF(prop1_getter_record,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop1\"",
|
||||
reinterpret_cast<intptr_t>(Prop1Getter));
|
||||
CHECK_NE(NULL,
|
||||
StrNStr(log.start(), prop1_getter_record.start(), log.length()));
|
||||
|
||||
EmbeddedVector<char, 100> prop1_setter_record;
|
||||
i::SNPrintF(prop1_setter_record,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"",
|
||||
reinterpret_cast<intptr_t>(Prop1Setter));
|
||||
CHECK_NE(NULL,
|
||||
StrNStr(log.start(), prop1_setter_record.start(), log.length()));
|
||||
EmbeddedVector<char, 100> prop1_setter_record;
|
||||
i::SNPrintF(prop1_setter_record,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"set prop1\"",
|
||||
reinterpret_cast<intptr_t>(Prop1Setter));
|
||||
CHECK_NE(NULL,
|
||||
StrNStr(log.start(), prop1_setter_record.start(), log.length()));
|
||||
|
||||
EmbeddedVector<char, 100> prop2_getter_record;
|
||||
i::SNPrintF(prop2_getter_record,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"",
|
||||
reinterpret_cast<intptr_t>(Prop2Getter));
|
||||
CHECK_NE(NULL,
|
||||
StrNStr(log.start(), prop2_getter_record.start(), log.length()));
|
||||
log.Dispose();
|
||||
}
|
||||
isolate->Dispose();
|
||||
EmbeddedVector<char, 100> prop2_getter_record;
|
||||
i::SNPrintF(prop2_getter_record,
|
||||
"code-creation,Callback,-2,0x%" V8PRIxPTR ",1,\"get prop2\"",
|
||||
reinterpret_cast<intptr_t>(Prop2Getter));
|
||||
CHECK_NE(NULL,
|
||||
StrNStr(log.start(), prop2_getter_record.start(), log.length()));
|
||||
log.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -448,63 +439,57 @@ TEST(EquivalenceOfLoggingAndTraversal) {
|
||||
// are using V8.
|
||||
|
||||
// Start with profiling to capture all code events from the beginning.
|
||||
v8::Isolate* isolate;
|
||||
{
|
||||
ScopedLoggerInitializer initialize_logger;
|
||||
isolate = initialize_logger.isolate();
|
||||
Logger* logger = initialize_logger.logger();
|
||||
ScopedLoggerInitializer initialize_logger;
|
||||
Logger* logger = initialize_logger.logger();
|
||||
|
||||
// Compile and run a function that creates other functions.
|
||||
CompileRun(
|
||||
"(function f(obj) {\n"
|
||||
" obj.test =\n"
|
||||
" (function a(j) { return function b() { return j; } })(100);\n"
|
||||
"})(this);");
|
||||
logger->StopProfiler();
|
||||
reinterpret_cast<i::Isolate*>(isolate)->heap()->CollectAllGarbage(
|
||||
i::Heap::kMakeHeapIterableMask);
|
||||
logger->StringEvent("test-logging-done", "");
|
||||
// Compile and run a function that creates other functions.
|
||||
CompileRun(
|
||||
"(function f(obj) {\n"
|
||||
" obj.test =\n"
|
||||
" (function a(j) { return function b() { return j; } })(100);\n"
|
||||
"})(this);");
|
||||
logger->StopProfiler();
|
||||
CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
|
||||
logger->StringEvent("test-logging-done", "");
|
||||
|
||||
// Iterate heap to find compiled functions, will write to log.
|
||||
logger->LogCompiledFunctions();
|
||||
logger->StringEvent("test-traversal-done", "");
|
||||
// Iterate heap to find compiled functions, will write to log.
|
||||
logger->LogCompiledFunctions();
|
||||
logger->StringEvent("test-traversal-done", "");
|
||||
|
||||
bool exists = false;
|
||||
i::Vector<const char> log(
|
||||
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
|
||||
CHECK(exists);
|
||||
v8::Handle<v8::String> log_str = v8::String::NewFromUtf8(
|
||||
isolate, log.start(), v8::String::kNormalString, log.length());
|
||||
initialize_logger.env()->Global()->Set(v8_str("_log"), log_str);
|
||||
bool exists = false;
|
||||
i::Vector<const char> log(
|
||||
i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
|
||||
CHECK(exists);
|
||||
v8::Handle<v8::String> log_str = v8::String::NewFromUtf8(
|
||||
CcTest::isolate(), log.start(), v8::String::kNormalString, log.length());
|
||||
initialize_logger.env()->Global()->Set(v8_str("_log"), log_str);
|
||||
|
||||
i::Vector<const unsigned char> source = TestSources::GetScriptsSource();
|
||||
v8::Handle<v8::String> source_str = v8::String::NewFromUtf8(
|
||||
isolate, reinterpret_cast<const char*>(source.start()),
|
||||
v8::String::kNormalString, source.length());
|
||||
v8::TryCatch try_catch;
|
||||
v8::Handle<v8::Script> script = CompileWithOrigin(source_str, "");
|
||||
if (script.IsEmpty()) {
|
||||
v8::String::Utf8Value exception(try_catch.Exception());
|
||||
printf("compile: %s\n", *exception);
|
||||
CHECK(false);
|
||||
}
|
||||
v8::Handle<v8::Value> result = script->Run();
|
||||
if (result.IsEmpty()) {
|
||||
v8::String::Utf8Value exception(try_catch.Exception());
|
||||
printf("run: %s\n", *exception);
|
||||
CHECK(false);
|
||||
}
|
||||
// The result either be a "true" literal or problem description.
|
||||
if (!result->IsTrue()) {
|
||||
v8::Local<v8::String> s = result->ToString();
|
||||
i::ScopedVector<char> data(s->Utf8Length() + 1);
|
||||
CHECK_NE(NULL, data.start());
|
||||
s->WriteUtf8(data.start());
|
||||
printf("%s\n", data.start());
|
||||
// Make sure that our output is written prior crash due to CHECK failure.
|
||||
fflush(stdout);
|
||||
CHECK(false);
|
||||
}
|
||||
i::Vector<const unsigned char> source = TestSources::GetScriptsSource();
|
||||
v8::Handle<v8::String> source_str = v8::String::NewFromUtf8(
|
||||
CcTest::isolate(), reinterpret_cast<const char*>(source.start()),
|
||||
v8::String::kNormalString, source.length());
|
||||
v8::TryCatch try_catch;
|
||||
v8::Handle<v8::Script> script = CompileWithOrigin(source_str, "");
|
||||
if (script.IsEmpty()) {
|
||||
v8::String::Utf8Value exception(try_catch.Exception());
|
||||
printf("compile: %s\n", *exception);
|
||||
CHECK(false);
|
||||
}
|
||||
v8::Handle<v8::Value> result = script->Run();
|
||||
if (result.IsEmpty()) {
|
||||
v8::String::Utf8Value exception(try_catch.Exception());
|
||||
printf("run: %s\n", *exception);
|
||||
CHECK(false);
|
||||
}
|
||||
// The result either be a "true" literal or problem description.
|
||||
if (!result->IsTrue()) {
|
||||
v8::Local<v8::String> s = result->ToString();
|
||||
i::ScopedVector<char> data(s->Utf8Length() + 1);
|
||||
CHECK_NE(NULL, data.start());
|
||||
s->WriteUtf8(data.start());
|
||||
printf("%s\n", data.start());
|
||||
// Make sure that our output is written prior crash due to CHECK failure.
|
||||
fflush(stdout);
|
||||
CHECK(false);
|
||||
}
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
@ -137,6 +137,8 @@ typedef int (*F5)(void*, void*, void*, void*, void*);
|
||||
|
||||
|
||||
TEST(LoadAndStoreWithRepresentation) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
|
@ -50,6 +50,8 @@ typedef F0Type* F0;
|
||||
|
||||
|
||||
TEST(LoadAndStoreWithRepresentation) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
|
@ -153,6 +153,7 @@ static void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) {
|
||||
|
||||
// Test that we can move a Smi value literally into a register.
|
||||
TEST(SmiMove) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -238,6 +239,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
// Test that we can compare smis for equality (and more).
|
||||
TEST(SmiCompare) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -286,6 +288,7 @@ TEST(SmiCompare) {
|
||||
|
||||
|
||||
TEST(Integer32ToSmi) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -412,6 +415,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm,
|
||||
|
||||
|
||||
TEST(Integer64PlusConstantToSmi) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -454,6 +458,7 @@ TEST(Integer64PlusConstantToSmi) {
|
||||
|
||||
|
||||
TEST(SmiCheck) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -699,6 +704,7 @@ void TestSmiNeg(MacroAssembler* masm, Label* exit, int id, int x) {
|
||||
|
||||
|
||||
TEST(SmiNeg) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -912,6 +918,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm,
|
||||
|
||||
|
||||
TEST(SmiAdd) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1130,6 +1137,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm,
|
||||
|
||||
|
||||
TEST(SmiSub) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1218,6 +1226,7 @@ void TestSmiMul(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiMul) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1321,6 +1330,7 @@ void TestSmiDiv(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiDiv) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1428,6 +1438,7 @@ void TestSmiMod(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiMod) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1522,6 +1533,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
|
||||
|
||||
|
||||
TEST(SmiIndex) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1588,6 +1600,7 @@ void TestSelectNonSmi(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiSelectNonSmi) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1664,6 +1677,7 @@ void TestSmiAnd(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiAnd) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1742,6 +1756,7 @@ void TestSmiOr(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiOr) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1822,6 +1837,7 @@ void TestSmiXor(MacroAssembler* masm, Label* exit, int id, int x, int y) {
|
||||
|
||||
|
||||
TEST(SmiXor) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1886,6 +1902,7 @@ void TestSmiNot(MacroAssembler* masm, Label* exit, int id, int x) {
|
||||
|
||||
|
||||
TEST(SmiNot) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -1979,6 +1996,7 @@ void TestSmiShiftLeft(MacroAssembler* masm, Label* exit, int id, int x) {
|
||||
|
||||
|
||||
TEST(SmiShiftLeft) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -2082,6 +2100,7 @@ void TestSmiShiftLogicalRight(MacroAssembler* masm,
|
||||
|
||||
|
||||
TEST(SmiShiftLogicalRight) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -2148,6 +2167,7 @@ void TestSmiShiftArithmeticRight(MacroAssembler* masm,
|
||||
|
||||
|
||||
TEST(SmiShiftArithmeticRight) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -2209,6 +2229,7 @@ void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) {
|
||||
|
||||
|
||||
TEST(PositiveSmiTimesPowerOfTwoToInteger64) {
|
||||
i::V8::Initialize(NULL);
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
@ -2246,6 +2267,7 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) {
|
||||
|
||||
|
||||
TEST(OperandOffset) {
|
||||
i::V8::Initialize(NULL);
|
||||
uint32_t data[256];
|
||||
for (uint32_t i = 0; i < 256; i++) { data[i] = i * 0x01010101; }
|
||||
|
||||
@ -2599,6 +2621,8 @@ TEST(OperandOffset) {
|
||||
|
||||
|
||||
TEST(LoadAndStoreWithRepresentation) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
|
@ -50,6 +50,8 @@ typedef F0Type* F0;
|
||||
|
||||
|
||||
TEST(LoadAndStoreWithRepresentation) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
|
||||
// Allocate an executable page of memory.
|
||||
size_t actual_size;
|
||||
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
|
||||
|
@ -34,16 +34,28 @@
|
||||
using namespace v8::internal;
|
||||
|
||||
|
||||
static const int64_t kRandomSeeds[] = {-1, 1, 42, 100, 1234567890, 987654321};
|
||||
static const int kMaxRuns = 12345;
|
||||
static const int kRandomSeeds[] = {
|
||||
-1, 1, 42, 100, 1234567890, 987654321
|
||||
};
|
||||
|
||||
|
||||
TEST(RandomSeedFlagIsUsed) {
|
||||
for (unsigned n = 0; n < arraysize(kRandomSeeds); ++n) {
|
||||
FLAG_random_seed = static_cast<int>(kRandomSeeds[n]);
|
||||
FLAG_random_seed = kRandomSeeds[n];
|
||||
v8::Isolate* i = v8::Isolate::New();
|
||||
v8::base::RandomNumberGenerator& rng =
|
||||
v8::base::RandomNumberGenerator& rng1 =
|
||||
*reinterpret_cast<Isolate*>(i)->random_number_generator();
|
||||
CHECK_EQ(kRandomSeeds[n], rng.initial_seed());
|
||||
v8::base::RandomNumberGenerator rng2(kRandomSeeds[n]);
|
||||
for (int k = 1; k <= kMaxRuns; ++k) {
|
||||
int64_t i1, i2;
|
||||
rng1.NextBytes(&i1, sizeof(i1));
|
||||
rng2.NextBytes(&i2, sizeof(i2));
|
||||
CHECK_EQ(i2, i1);
|
||||
CHECK_EQ(rng2.NextInt(), rng1.NextInt());
|
||||
CHECK_EQ(rng2.NextInt(k), rng1.NextInt(k));
|
||||
CHECK_EQ(rng2.NextDouble(), rng1.NextDouble());
|
||||
}
|
||||
i->Dispose();
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ using namespace v8::internal;
|
||||
|
||||
|
||||
static bool CheckParse(const char* input) {
|
||||
V8::Initialize(NULL);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Zone zone(CcTest::i_isolate());
|
||||
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
|
||||
@ -95,6 +96,7 @@ static bool CheckParse(const char* input) {
|
||||
|
||||
|
||||
static void CheckParseEq(const char* input, const char* expected) {
|
||||
V8::Initialize(NULL);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Zone zone(CcTest::i_isolate());
|
||||
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
|
||||
@ -110,6 +112,7 @@ static void CheckParseEq(const char* input, const char* expected) {
|
||||
|
||||
|
||||
static bool CheckSimple(const char* input) {
|
||||
V8::Initialize(NULL);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Zone zone(CcTest::i_isolate());
|
||||
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
|
||||
@ -128,6 +131,7 @@ struct MinMaxPair {
|
||||
|
||||
|
||||
static MinMaxPair CheckMinMaxMatch(const char* input) {
|
||||
V8::Initialize(NULL);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Zone zone(CcTest::i_isolate());
|
||||
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
|
||||
@ -152,6 +156,8 @@ static MinMaxPair CheckMinMaxMatch(const char* input) {
|
||||
}
|
||||
|
||||
TEST(Parser) {
|
||||
V8::Initialize(NULL);
|
||||
|
||||
CHECK_PARSE_ERROR("?");
|
||||
|
||||
CheckParseEq("abc", "'abc'");
|
||||
@ -401,6 +407,7 @@ TEST(ParserRegression) {
|
||||
|
||||
static void ExpectError(const char* input,
|
||||
const char* expected) {
|
||||
V8::Initialize(NULL);
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Zone zone(CcTest::i_isolate());
|
||||
FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
|
||||
@ -487,6 +494,7 @@ static void TestCharacterClassEscapes(uc16 c, bool (pred)(uc16 c)) {
|
||||
|
||||
|
||||
TEST(CharacterClassEscapes) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
TestCharacterClassEscapes('.', IsRegExpNewline);
|
||||
TestCharacterClassEscapes('d', IsDigit);
|
||||
TestCharacterClassEscapes('D', NotDigit);
|
||||
@ -499,6 +507,7 @@ TEST(CharacterClassEscapes) {
|
||||
|
||||
static RegExpNode* Compile(const char* input, bool multiline, bool is_one_byte,
|
||||
Zone* zone) {
|
||||
V8::Initialize(NULL);
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
FlatStringReader reader(isolate, CStrVector(input));
|
||||
RegExpCompileData compile_data;
|
||||
@ -555,6 +564,7 @@ static unsigned PseudoRandom(int i, int j) {
|
||||
|
||||
|
||||
TEST(SplayTreeSimple) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
static const unsigned kLimit = 1000;
|
||||
Zone zone(CcTest::i_isolate());
|
||||
ZoneSplayTree<TestConfig> tree(&zone);
|
||||
@ -607,6 +617,7 @@ TEST(SplayTreeSimple) {
|
||||
|
||||
|
||||
TEST(DispatchTableConstruction) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
// Initialize test data.
|
||||
static const int kLimit = 1000;
|
||||
static const int kRangeCount = 8;
|
||||
@ -1351,6 +1362,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) {
|
||||
#else // V8_INTERPRETED_REGEXP
|
||||
|
||||
TEST(MacroAssembler) {
|
||||
V8::Initialize(NULL);
|
||||
byte codes[1024];
|
||||
Zone zone(CcTest::i_isolate());
|
||||
RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024), &zone);
|
||||
@ -1416,6 +1428,7 @@ TEST(MacroAssembler) {
|
||||
|
||||
|
||||
TEST(AddInverseToTable) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
static const int kLimit = 1000;
|
||||
static const int kRangeCount = 16;
|
||||
for (int t = 0; t < 10; t++) {
|
||||
@ -1575,6 +1588,7 @@ static void TestSimpleRangeCaseIndependence(CharacterRange input,
|
||||
|
||||
|
||||
TEST(CharacterRangeCaseIndependence) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
TestSimpleRangeCaseIndependence(CharacterRange::Singleton('a'),
|
||||
CharacterRange::Singleton('A'));
|
||||
TestSimpleRangeCaseIndependence(CharacterRange::Singleton('z'),
|
||||
@ -1616,6 +1630,7 @@ static bool InClass(uc16 c, ZoneList<CharacterRange>* ranges) {
|
||||
|
||||
|
||||
TEST(CharClassDifference) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
Zone zone(CcTest::i_isolate());
|
||||
ZoneList<CharacterRange>* base =
|
||||
new(&zone) ZoneList<CharacterRange>(1, &zone);
|
||||
@ -1643,6 +1658,7 @@ TEST(CharClassDifference) {
|
||||
|
||||
|
||||
TEST(CanonicalizeCharacterSets) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
Zone zone(CcTest::i_isolate());
|
||||
ZoneList<CharacterRange>* list =
|
||||
new(&zone) ZoneList<CharacterRange>(4, &zone);
|
||||
@ -1704,6 +1720,7 @@ TEST(CanonicalizeCharacterSets) {
|
||||
|
||||
|
||||
TEST(CharacterRangeMerge) {
|
||||
v8::internal::V8::Initialize(NULL);
|
||||
Zone zone(CcTest::i_isolate());
|
||||
ZoneList<CharacterRange> l1(4, &zone);
|
||||
ZoneList<CharacterRange> l2(4, &zone);
|
||||
@ -1791,5 +1808,6 @@ TEST(CharacterRangeMerge) {
|
||||
|
||||
|
||||
TEST(Graph) {
|
||||
V8::Initialize(NULL);
|
||||
Execute("\\b\\w+\\b", false, true, true);
|
||||
}
|
||||
|
@ -45,6 +45,42 @@
|
||||
|
||||
using namespace v8::internal;
|
||||
|
||||
static const unsigned kCounters = 256;
|
||||
static int local_counters[kCounters];
|
||||
static const char* local_counter_names[kCounters];
|
||||
|
||||
|
||||
static unsigned CounterHash(const char* s) {
|
||||
unsigned hash = 0;
|
||||
while (*++s) {
|
||||
hash |= hash << 5;
|
||||
hash += *s;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
// Callback receiver to track counters in test.
|
||||
static int* counter_function(const char* name) {
|
||||
unsigned hash = CounterHash(name) % kCounters;
|
||||
unsigned original_hash = hash;
|
||||
USE(original_hash);
|
||||
while (true) {
|
||||
if (local_counter_names[hash] == name) {
|
||||
return &local_counters[hash];
|
||||
}
|
||||
if (local_counter_names[hash] == 0) {
|
||||
local_counter_names[hash] = name;
|
||||
return &local_counters[hash];
|
||||
}
|
||||
if (strcmp(local_counter_names[hash], name) == 0) {
|
||||
return &local_counters[hash];
|
||||
}
|
||||
hash = (hash + 1) % kCounters;
|
||||
DCHECK(hash != original_hash); // Hash table has been filled up.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
static Address AddressOf(T id) {
|
||||
@ -65,6 +101,7 @@ static int make_code(TypeCode type, int id) {
|
||||
|
||||
TEST(ExternalReferenceEncoder) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->stats_table()->SetCounterFunction(counter_function);
|
||||
v8::V8::Initialize();
|
||||
|
||||
ExternalReferenceEncoder encoder(isolate);
|
||||
@ -72,6 +109,10 @@ TEST(ExternalReferenceEncoder) {
|
||||
Encode(encoder, Builtins::kArrayCode));
|
||||
CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort),
|
||||
Encode(encoder, Runtime::kAbort));
|
||||
ExternalReference total_compile_size =
|
||||
ExternalReference(isolate->counters()->total_compile_size());
|
||||
CHECK_EQ(make_code(STATS_COUNTER, Counters::k_total_compile_size),
|
||||
encoder.Encode(total_compile_size.address()));
|
||||
ExternalReference stack_limit_address =
|
||||
ExternalReference::address_of_stack_limit(isolate);
|
||||
CHECK_EQ(make_code(UNCLASSIFIED, 2),
|
||||
@ -95,6 +136,7 @@ TEST(ExternalReferenceEncoder) {
|
||||
|
||||
TEST(ExternalReferenceDecoder) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->stats_table()->SetCounterFunction(counter_function);
|
||||
v8::V8::Initialize();
|
||||
|
||||
ExternalReferenceDecoder decoder(isolate);
|
||||
@ -103,6 +145,12 @@ TEST(ExternalReferenceDecoder) {
|
||||
CHECK_EQ(AddressOf(Runtime::kAbort),
|
||||
decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION,
|
||||
Runtime::kAbort)));
|
||||
ExternalReference total_compile_size =
|
||||
ExternalReference(isolate->counters()->total_compile_size());
|
||||
CHECK_EQ(total_compile_size.address(),
|
||||
decoder.Decode(
|
||||
make_code(STATS_COUNTER,
|
||||
Counters::k_total_compile_size)));
|
||||
CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
|
||||
decoder.Decode(make_code(UNCLASSIFIED, 2)));
|
||||
CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
|
||||
@ -194,41 +242,40 @@ static bool WriteToFile(Isolate* isolate, const char* snapshot_file) {
|
||||
}
|
||||
|
||||
|
||||
static void Serialize(v8::Isolate* isolate) {
|
||||
static void Serialize() {
|
||||
// We have to create one context. One reason for this is so that the builtins
|
||||
// can be loaded from v8natives.js and their addresses can be processed. This
|
||||
// will clear the pending fixups array, which would otherwise contain GC roots
|
||||
// that would confuse the serialization/deserialization process.
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
{
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Context::New(isolate);
|
||||
}
|
||||
|
||||
Isolate* internal_isolate = reinterpret_cast<Isolate*>(isolate);
|
||||
Isolate* internal_isolate = CcTest::i_isolate();
|
||||
internal_isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "serialize");
|
||||
WriteToFile(internal_isolate, FLAG_testing_serialization_file);
|
||||
}
|
||||
|
||||
|
||||
// Test that the whole heap can be serialized.
|
||||
UNINITIALIZED_TEST(Serialize) {
|
||||
TEST(Serialize) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate::CreateParams params;
|
||||
params.enable_serializer = true;
|
||||
v8::Isolate* isolate = v8::Isolate::New(params);
|
||||
Serialize(isolate);
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
Serialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test that heap serialization is non-destructive.
|
||||
UNINITIALIZED_TEST(SerializeTwice) {
|
||||
TEST(SerializeTwice) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate::CreateParams params;
|
||||
params.enable_serializer = true;
|
||||
v8::Isolate* isolate = v8::Isolate::New(params);
|
||||
Serialize(isolate);
|
||||
Serialize(isolate);
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
Serialize();
|
||||
Serialize();
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,370 +319,330 @@ static void ReserveSpaceForSnapshot(Deserializer* deserializer,
|
||||
}
|
||||
|
||||
|
||||
v8::Isolate* InitializeFromFile(const char* snapshot_file) {
|
||||
bool InitializeFromFile(const char* snapshot_file) {
|
||||
int len;
|
||||
byte* str = ReadBytes(snapshot_file, &len);
|
||||
if (!str) return NULL;
|
||||
v8::Isolate* v8_isolate = NULL;
|
||||
if (!str) return false;
|
||||
bool success;
|
||||
{
|
||||
SnapshotByteSource source(str, len);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, snapshot_file);
|
||||
Isolate* isolate = Isolate::NewForTesting();
|
||||
v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
isolate->Init(&deserializer);
|
||||
success = V8::Initialize(&deserializer);
|
||||
}
|
||||
DeleteArray(str);
|
||||
return v8_isolate;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static v8::Isolate* Deserialize() {
|
||||
v8::Isolate* isolate = InitializeFromFile(FLAG_testing_serialization_file);
|
||||
CHECK(isolate);
|
||||
return isolate;
|
||||
static void Deserialize() {
|
||||
CHECK(InitializeFromFile(FLAG_testing_serialization_file));
|
||||
}
|
||||
|
||||
|
||||
static void SanityCheck(v8::Isolate* v8_isolate) {
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
v8::HandleScope scope(v8_isolate);
|
||||
static void SanityCheck() {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
#ifdef VERIFY_HEAP
|
||||
isolate->heap()->Verify();
|
||||
CcTest::heap()->Verify();
|
||||
#endif
|
||||
CHECK(isolate->global_object()->IsJSObject());
|
||||
CHECK(isolate->native_context()->IsContext());
|
||||
CHECK(isolate->heap()->string_table()->IsStringTable());
|
||||
CHECK(CcTest::heap()->string_table()->IsStringTable());
|
||||
isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Empty"));
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_DEPENDENT_TEST(Deserialize, Serialize) {
|
||||
DEPENDENT_TEST(Deserialize, Serialize) {
|
||||
// The serialize-deserialize tests only work if the VM is built without
|
||||
// serialization. That doesn't matter. We don't need to be able to
|
||||
// serialize a snapshot in a VM that is booted from a snapshot.
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate* isolate = Deserialize();
|
||||
{
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
Deserialize();
|
||||
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
|
||||
SanityCheck(isolate);
|
||||
}
|
||||
isolate->Dispose();
|
||||
SanityCheck();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerialization,
|
||||
SerializeTwice) {
|
||||
DEPENDENT_TEST(DeserializeFromSecondSerialization, SerializeTwice) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate* isolate = Deserialize();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
Deserialize();
|
||||
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
|
||||
SanityCheck(isolate);
|
||||
}
|
||||
isolate->Dispose();
|
||||
SanityCheck();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
|
||||
DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate* isolate = Deserialize();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
Deserialize();
|
||||
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
|
||||
const char* c_source = "\"1234\".length";
|
||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
|
||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||||
CHECK_EQ(4, script->Run()->Int32Value());
|
||||
}
|
||||
isolate->Dispose();
|
||||
const char* c_source = "\"1234\".length";
|
||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
|
||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||||
CHECK_EQ(4, script->Run()->Int32Value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
|
||||
SerializeTwice) {
|
||||
DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
|
||||
SerializeTwice) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate* isolate = Deserialize();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
Deserialize();
|
||||
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
v8::Local<v8::Context> env = v8::Context::New(isolate);
|
||||
env->Enter();
|
||||
|
||||
const char* c_source = "\"1234\".length";
|
||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
|
||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||||
CHECK_EQ(4, script->Run()->Int32Value());
|
||||
}
|
||||
isolate->Dispose();
|
||||
const char* c_source = "\"1234\".length";
|
||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
|
||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||||
CHECK_EQ(4, script->Run()->Int32Value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(PartialSerialization) {
|
||||
TEST(PartialSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate::CreateParams params;
|
||||
params.enable_serializer = true;
|
||||
v8::Isolate* v8_isolate = v8::Isolate::New(params);
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
v8_isolate->Enter();
|
||||
{
|
||||
Heap* heap = isolate->heap();
|
||||
|
||||
v8::Persistent<v8::Context> env;
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
|
||||
}
|
||||
DCHECK(!env.IsEmpty());
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
|
||||
}
|
||||
// Make sure all builtin scripts are cached.
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
|
||||
isolate->bootstrapper()->NativesSourceLookup(i);
|
||||
}
|
||||
}
|
||||
heap->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
heap->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
|
||||
Object* raw_foo;
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo");
|
||||
DCHECK(!foo.IsEmpty());
|
||||
raw_foo = *(v8::Utils::OpenHandle(*foo));
|
||||
}
|
||||
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
|
||||
}
|
||||
env.Reset();
|
||||
|
||||
FileByteSink startup_sink(startup_name.start());
|
||||
StartupSerializer startup_serializer(isolate, &startup_sink);
|
||||
startup_serializer.SerializeStrongReferences();
|
||||
|
||||
FileByteSink partial_sink(FLAG_testing_serialization_file);
|
||||
PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
|
||||
p_ser.Serialize(&raw_foo);
|
||||
startup_serializer.SerializeWeakReferences();
|
||||
|
||||
partial_sink.WriteSpaceUsed(
|
||||
p_ser.CurrentAllocationAddress(NEW_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CODE_SPACE),
|
||||
p_ser.CurrentAllocationAddress(MAP_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CELL_SPACE),
|
||||
p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
|
||||
startup_sink.WriteSpaceUsed(
|
||||
startup_serializer.CurrentAllocationAddress(NEW_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CODE_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(MAP_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CELL_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
startup_name.Dispose();
|
||||
}
|
||||
v8_isolate->Exit();
|
||||
v8_isolate->Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start());
|
||||
CHECK(v8_isolate);
|
||||
startup_name.Dispose();
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
|
||||
const char* file_name = FLAG_testing_serialization_file;
|
||||
|
||||
int snapshot_size = 0;
|
||||
byte* snapshot = ReadBytes(file_name, &snapshot_size);
|
||||
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
Object* root;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root);
|
||||
CHECK(root->IsString());
|
||||
}
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root_handle(root, isolate);
|
||||
|
||||
|
||||
Object* root2;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root2);
|
||||
CHECK(root2->IsString());
|
||||
CHECK(*root_handle == root2);
|
||||
}
|
||||
}
|
||||
v8_isolate->Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_TEST(ContextSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
v8::Isolate::CreateParams params;
|
||||
params.enable_serializer = true;
|
||||
v8::Isolate* v8_isolate = v8::Isolate::New(params);
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
Heap* heap = isolate->heap();
|
||||
|
||||
v8::Persistent<v8::Context> env;
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
|
||||
v8::Persistent<v8::Context> env;
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
|
||||
}
|
||||
DCHECK(!env.IsEmpty());
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
|
||||
}
|
||||
// Make sure all builtin scripts are cached.
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
|
||||
isolate->bootstrapper()->NativesSourceLookup(i);
|
||||
}
|
||||
}
|
||||
// If we don't do this then we end up with a stray root pointing at the
|
||||
// context even after we have disposed of env.
|
||||
heap->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
|
||||
}
|
||||
|
||||
i::Object* raw_context = *v8::Utils::OpenPersistent(env);
|
||||
|
||||
env.Reset();
|
||||
|
||||
FileByteSink startup_sink(startup_name.start());
|
||||
StartupSerializer startup_serializer(isolate, &startup_sink);
|
||||
startup_serializer.SerializeStrongReferences();
|
||||
|
||||
FileByteSink partial_sink(FLAG_testing_serialization_file);
|
||||
PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
|
||||
p_ser.Serialize(&raw_context);
|
||||
startup_serializer.SerializeWeakReferences();
|
||||
|
||||
partial_sink.WriteSpaceUsed(
|
||||
p_ser.CurrentAllocationAddress(NEW_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CODE_SPACE),
|
||||
p_ser.CurrentAllocationAddress(MAP_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CELL_SPACE),
|
||||
p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
|
||||
startup_sink.WriteSpaceUsed(
|
||||
startup_serializer.CurrentAllocationAddress(NEW_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CODE_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(MAP_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CELL_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
startup_name.Dispose();
|
||||
HandleScope scope(isolate);
|
||||
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
|
||||
}
|
||||
v8_isolate->Dispose();
|
||||
DCHECK(!env.IsEmpty());
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
|
||||
}
|
||||
// Make sure all builtin scripts are cached.
|
||||
{ HandleScope scope(isolate);
|
||||
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
|
||||
isolate->bootstrapper()->NativesSourceLookup(i);
|
||||
}
|
||||
}
|
||||
heap->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
heap->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
|
||||
Object* raw_foo;
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo");
|
||||
DCHECK(!foo.IsEmpty());
|
||||
raw_foo = *(v8::Utils::OpenHandle(*foo));
|
||||
}
|
||||
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
|
||||
}
|
||||
env.Reset();
|
||||
|
||||
FileByteSink startup_sink(startup_name.start());
|
||||
StartupSerializer startup_serializer(isolate, &startup_sink);
|
||||
startup_serializer.SerializeStrongReferences();
|
||||
|
||||
FileByteSink partial_sink(FLAG_testing_serialization_file);
|
||||
PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
|
||||
p_ser.Serialize(&raw_foo);
|
||||
startup_serializer.SerializeWeakReferences();
|
||||
|
||||
partial_sink.WriteSpaceUsed(
|
||||
p_ser.CurrentAllocationAddress(NEW_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CODE_SPACE),
|
||||
p_ser.CurrentAllocationAddress(MAP_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CELL_SPACE),
|
||||
p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
|
||||
startup_sink.WriteSpaceUsed(
|
||||
startup_serializer.CurrentAllocationAddress(NEW_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CODE_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(MAP_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CELL_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
startup_name.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
|
||||
DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start());
|
||||
CHECK(v8_isolate);
|
||||
CHECK(InitializeFromFile(startup_name.start()));
|
||||
startup_name.Dispose();
|
||||
|
||||
const char* file_name = FLAG_testing_serialization_file;
|
||||
|
||||
int snapshot_size = 0;
|
||||
byte* snapshot = ReadBytes(file_name, &snapshot_size);
|
||||
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Object* root;
|
||||
{
|
||||
v8::Isolate::Scope isolate_scope(v8_isolate);
|
||||
|
||||
const char* file_name = FLAG_testing_serialization_file;
|
||||
|
||||
int snapshot_size = 0;
|
||||
byte* snapshot = ReadBytes(file_name, &snapshot_size);
|
||||
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
Object* root;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root);
|
||||
CHECK(root->IsContext());
|
||||
}
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root_handle(root, isolate);
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root);
|
||||
CHECK(root->IsString());
|
||||
}
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root_handle(root, isolate);
|
||||
|
||||
|
||||
Object* root2;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root2);
|
||||
CHECK(root2->IsContext());
|
||||
CHECK(*root_handle != root2);
|
||||
Object* root2;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root2);
|
||||
CHECK(root2->IsString());
|
||||
CHECK(*root_handle == root2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(ContextSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
CcTest::i_isolate()->enable_serializer();
|
||||
v8::V8::Initialize();
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
Heap* heap = isolate->heap();
|
||||
|
||||
v8::Persistent<v8::Context> env;
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
env.Reset(v8_isolate, v8::Context::New(v8_isolate));
|
||||
}
|
||||
DCHECK(!env.IsEmpty());
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
|
||||
}
|
||||
// Make sure all builtin scripts are cached.
|
||||
{ HandleScope scope(isolate);
|
||||
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
|
||||
isolate->bootstrapper()->NativesSourceLookup(i);
|
||||
}
|
||||
}
|
||||
v8_isolate->Dispose();
|
||||
// If we don't do this then we end up with a stray root pointing at the
|
||||
// context even after we have disposed of env.
|
||||
heap->CollectAllGarbage(Heap::kNoGCFlags);
|
||||
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(v8_isolate);
|
||||
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
|
||||
}
|
||||
|
||||
i::Object* raw_context = *v8::Utils::OpenPersistent(env);
|
||||
|
||||
env.Reset();
|
||||
|
||||
FileByteSink startup_sink(startup_name.start());
|
||||
StartupSerializer startup_serializer(isolate, &startup_sink);
|
||||
startup_serializer.SerializeStrongReferences();
|
||||
|
||||
FileByteSink partial_sink(FLAG_testing_serialization_file);
|
||||
PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
|
||||
p_ser.Serialize(&raw_context);
|
||||
startup_serializer.SerializeWeakReferences();
|
||||
|
||||
partial_sink.WriteSpaceUsed(
|
||||
p_ser.CurrentAllocationAddress(NEW_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CODE_SPACE),
|
||||
p_ser.CurrentAllocationAddress(MAP_SPACE),
|
||||
p_ser.CurrentAllocationAddress(CELL_SPACE),
|
||||
p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
|
||||
startup_sink.WriteSpaceUsed(
|
||||
startup_serializer.CurrentAllocationAddress(NEW_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CODE_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(MAP_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(CELL_SPACE),
|
||||
startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
|
||||
startup_name.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
|
||||
if (!Snapshot::HaveASnapshotToStartFrom()) {
|
||||
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
|
||||
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
|
||||
SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
|
||||
|
||||
CHECK(InitializeFromFile(startup_name.start()));
|
||||
startup_name.Dispose();
|
||||
|
||||
const char* file_name = FLAG_testing_serialization_file;
|
||||
|
||||
int snapshot_size = 0;
|
||||
byte* snapshot = ReadBytes(file_name, &snapshot_size);
|
||||
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Object* root;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root);
|
||||
CHECK(root->IsContext());
|
||||
}
|
||||
HandleScope handle_scope(isolate);
|
||||
Handle<Object> root_handle(root, isolate);
|
||||
|
||||
|
||||
Object* root2;
|
||||
{
|
||||
SnapshotByteSource source(snapshot, snapshot_size);
|
||||
Deserializer deserializer(&source);
|
||||
ReserveSpaceForSnapshot(&deserializer, file_name);
|
||||
deserializer.DeserializePartial(isolate, &root2);
|
||||
CHECK(root2->IsContext());
|
||||
CHECK(*root_handle != root2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -792,6 +799,7 @@ TEST(SerializeToplevelIsolates) {
|
||||
v8::ScriptCompiler::CachedData* cache;
|
||||
|
||||
v8::Isolate* isolate1 = v8::Isolate::New();
|
||||
v8::Isolate* isolate2 = v8::Isolate::New();
|
||||
{
|
||||
v8::Isolate::Scope iscope(isolate1);
|
||||
v8::HandleScope scope(isolate1);
|
||||
@ -815,7 +823,6 @@ TEST(SerializeToplevelIsolates) {
|
||||
}
|
||||
isolate1->Dispose();
|
||||
|
||||
v8::Isolate* isolate2 = v8::Isolate::New();
|
||||
{
|
||||
v8::Isolate::Scope iscope(isolate2);
|
||||
v8::HandleScope scope(isolate2);
|
||||
|
@ -205,7 +205,9 @@ static void VerifyMemoryChunk(Isolate* isolate,
|
||||
|
||||
TEST(Regress3540) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->InitializeLoggingAndCounters();
|
||||
Heap* heap = isolate->heap();
|
||||
CHECK(heap->ConfigureHeapDefault());
|
||||
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
|
||||
CHECK(
|
||||
memory_allocator->SetUp(heap->MaxReserved(), heap->MaxExecutableSize()));
|
||||
@ -239,7 +241,9 @@ static unsigned int Pseudorandom() {
|
||||
|
||||
TEST(MemoryChunk) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->InitializeLoggingAndCounters();
|
||||
Heap* heap = isolate->heap();
|
||||
CHECK(heap->ConfigureHeapDefault());
|
||||
|
||||
size_t reserve_area_size = 1 * MB;
|
||||
size_t initial_commit_area_size, second_commit_area_size;
|
||||
@ -293,7 +297,9 @@ TEST(MemoryChunk) {
|
||||
|
||||
TEST(MemoryAllocator) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->InitializeLoggingAndCounters();
|
||||
Heap* heap = isolate->heap();
|
||||
CHECK(isolate->heap()->ConfigureHeapDefault());
|
||||
|
||||
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
|
||||
CHECK(memory_allocator->SetUp(heap->MaxReserved(),
|
||||
@ -340,7 +346,9 @@ TEST(MemoryAllocator) {
|
||||
|
||||
TEST(NewSpace) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->InitializeLoggingAndCounters();
|
||||
Heap* heap = isolate->heap();
|
||||
CHECK(heap->ConfigureHeapDefault());
|
||||
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
|
||||
CHECK(memory_allocator->SetUp(heap->MaxReserved(),
|
||||
heap->MaxExecutableSize()));
|
||||
@ -366,7 +374,9 @@ TEST(NewSpace) {
|
||||
|
||||
TEST(OldSpace) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
isolate->InitializeLoggingAndCounters();
|
||||
Heap* heap = isolate->heap();
|
||||
CHECK(heap->ConfigureHeapDefault());
|
||||
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
|
||||
CHECK(memory_allocator->SetUp(heap->MaxReserved(),
|
||||
heap->MaxExecutableSize()));
|
||||
|
@ -367,8 +367,6 @@
|
||||
# Currently always deopt on minus zero
|
||||
'math-floor-of-div-minus-zero': [SKIP],
|
||||
|
||||
'math-floor-of-div-nosudiv': [SKIP],
|
||||
|
||||
############################################################################
|
||||
# Slow tests.
|
||||
'regress/regress-2185-2': [PASS, SLOW],
|
||||
|
@ -180,11 +180,10 @@ v8::base::TimeDelta ProcessFile(
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
v8::V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
Encoding encoding = LATIN1;
|
||||
bool print_tokens = false;
|
||||
std::vector<std::string> fnames;
|
||||
|
@ -123,11 +123,10 @@ std::pair<v8::base::TimeDelta, v8::base::TimeDelta> RunBaselineParser(
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
v8::V8::InitializeICU();
|
||||
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
|
||||
v8::V8::InitializePlatform(platform);
|
||||
v8::V8::Initialize();
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
Encoding encoding = LATIN1;
|
||||
std::vector<std::string> fnames;
|
||||
std::string benchmark;
|
||||
|
Loading…
Reference in New Issue
Block a user