Merge v8 from https://chromium.googlesource.com/external/v8.git at e900018c7a2a695fde788911564da37535c7e736
This commit was generated by merge_from_chromium.py.
Change-Id: I153c99bd5ba06b6834630a43653d7fe1ce743596
diff --git a/ChangeLog b/ChangeLog
index 13d0a22..2e40db1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-09-03: Version 3.21.9
+
+ Deprecated Persistent functions which were marked to be deprecated.
+
+ Allowed uncacheable identifiers to go generic (issue 2867).
+
+ Performance and stability improvements on all platforms.
+
+
2013-09-02: Version 3.21.8
Added scriptId to StackTrace frames (issue 2865).
@@ -139,7 +148,7 @@
Performance and stability improvements on all platforms.
-2013-08-07: Version 3.20.14
+2013-08-07: Version 3.20.15
Exposed eternal handle api.
diff --git a/include/v8.h b/include/v8.h
index 13842ba..1b676de 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -634,8 +634,7 @@
* This handle's reference, and any other references to the storage
* cell remain and IsEmpty will still return false.
*/
- // TODO(dcarney): deprecate
- V8_INLINE(void Dispose(Isolate* isolate)) { Dispose(); }
+ V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Dispose(); }
/**
* Make the reference to this object weak. When only weak handles
@@ -667,8 +666,7 @@
V8_INLINE(void ClearWeak());
- // TODO(dcarney): deprecate
- V8_INLINE(void ClearWeak(Isolate* isolate)) { ClearWeak(); }
+ V8_DEPRECATED(V8_INLINE(void ClearWeak(Isolate* isolate))) { ClearWeak(); }
/**
* Marks the reference to this object independent. Garbage collector is free
@@ -678,8 +676,9 @@
*/
V8_INLINE(void MarkIndependent());
- // TODO(dcarney): deprecate
- V8_INLINE(void MarkIndependent(Isolate* isolate)) { MarkIndependent(); }
+ V8_DEPRECATED(V8_INLINE(void MarkIndependent(Isolate* isolate))) {
+ MarkIndependent();
+ }
/**
* Marks the reference to this object partially dependent. Partially dependent
@@ -691,29 +690,29 @@
*/
V8_INLINE(void MarkPartiallyDependent());
- // TODO(dcarney): deprecate
- V8_INLINE(void MarkPartiallyDependent(Isolate* isolate)) {
+ V8_DEPRECATED(V8_INLINE(void MarkPartiallyDependent(Isolate* isolate))) {
MarkPartiallyDependent();
}
V8_INLINE(bool IsIndependent() const);
- // TODO(dcarney): deprecate
- V8_INLINE(bool IsIndependent(Isolate* isolate) const) {
+ V8_DEPRECATED(V8_INLINE(bool IsIndependent(Isolate* isolate)) const) {
return IsIndependent();
}
/** Checks if the handle holds the only reference to an object. */
V8_INLINE(bool IsNearDeath() const);
- // TODO(dcarney): deprecate
- V8_INLINE(bool IsNearDeath(Isolate* isolate) const) { return IsNearDeath(); }
+ V8_DEPRECATED(V8_INLINE(bool IsNearDeath(Isolate* isolate)) const) {
+ return IsNearDeath();
+ }
/** Returns true if the handle's reference is weak. */
V8_INLINE(bool IsWeak() const);
- // TODO(dcarney): deprecate
- V8_INLINE(bool IsWeak(Isolate* isolate) const) { return IsWeak(); }
+ V8_DEPRECATED(V8_INLINE(bool IsWeak(Isolate* isolate)) const) {
+ return IsWeak();
+ }
/**
* Assigns a wrapper class ID to the handle. See RetainedObjectInfo interface
@@ -721,8 +720,8 @@
*/
V8_INLINE(void SetWrapperClassId(uint16_t class_id));
- // TODO(dcarney): deprecate
- V8_INLINE(void SetWrapperClassId(Isolate* isolate, uint16_t class_id)) {
+ V8_DEPRECATED(
+ V8_INLINE(void SetWrapperClassId(Isolate * isolate, uint16_t class_id))) {
SetWrapperClassId(class_id);
}
@@ -732,8 +731,7 @@
*/
V8_INLINE(uint16_t WrapperClassId() const);
- // TODO(dcarney): deprecate
- V8_INLINE(uint16_t WrapperClassId(Isolate* isolate) const) {
+ V8_DEPRECATED(V8_INLINE(uint16_t WrapperClassId(Isolate* isolate)) const) {
return WrapperClassId();
}
@@ -5736,7 +5734,7 @@
template <class T>
void Persistent<T>::Reset(Isolate* isolate, const Handle<T>& other) {
- Dispose(isolate);
+ Dispose();
#ifdef V8_USE_UNSAFE_HANDLES
*this = *New(isolate, other);
#else
@@ -5754,7 +5752,7 @@
#ifndef V8_USE_UNSAFE_HANDLES
template <class T>
void Persistent<T>::Reset(Isolate* isolate, const Persistent<T>& other) {
- Dispose(isolate);
+ Dispose();
if (other.IsEmpty()) {
this->val_ = NULL;
return;
diff --git a/samples/process.cc b/samples/process.cc
index 844aee3..e6f2ee3 100644
--- a/samples/process.cc
+++ b/samples/process.cc
@@ -291,9 +291,8 @@
// Dispose the persistent handles. When noone else has any
// references to the objects stored in the handles they will be
// automatically reclaimed.
- Isolate* isolate = GetIsolate();
- context_.Dispose(isolate);
- process_.Dispose(isolate);
+ context_.Dispose();
+ process_.Dispose();
}
diff --git a/src/accessors.cc b/src/accessors.cc
index b87d921..766d4da 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -127,9 +127,11 @@
Handle<Object> value_handle(value, isolate);
bool has_exception;
- Handle<Object> uint32_v = Execution::ToUint32(value_handle, &has_exception);
+ Handle<Object> uint32_v =
+ Execution::ToUint32(isolate, value_handle, &has_exception);
if (has_exception) return Failure::Exception();
- Handle<Object> number_v = Execution::ToNumber(value_handle, &has_exception);
+ Handle<Object> number_v =
+ Execution::ToNumber(isolate, value_handle, &has_exception);
if (has_exception) return Failure::Exception();
if (uint32_v->Number() == number_v->Number()) {
diff --git a/src/api.cc b/src/api.cc
index aecb58c..4b80555 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -220,25 +220,27 @@
// HeapIterator here without doing a special GC.
isolate->heap()->RecordStats(&heap_stats, false);
}
- i::V8::SetFatalError();
+ isolate->SignalFatalError();
FatalErrorCallback callback = GetFatalErrorHandler();
const char* message = "Allocation failed - process out of memory";
callback(location, message);
// If the callback returns, we stop execution.
- UNREACHABLE();
+ FATAL("API fatal error handler returned after process out of memory");
}
bool Utils::ReportApiFailure(const char* location, const char* message) {
FatalErrorCallback callback = GetFatalErrorHandler();
callback(location, message);
- i::V8::SetFatalError();
+ i::Isolate* isolate = i::Isolate::Current();
+ isolate->SignalFatalError();
return false;
}
bool V8::IsDead() {
- return i::V8::IsDead();
+ i::Isolate* isolate = i::Isolate::Current();
+ return isolate->IsDead();
}
@@ -277,7 +279,7 @@
*/
static inline bool IsDeadCheck(i::Isolate* isolate, const char* location) {
return !isolate->IsInitialized()
- && i::V8::IsDead() ? ReportV8Dead(location) : false;
+ && isolate->IsDead() ? ReportV8Dead(location) : false;
}
@@ -2738,7 +2740,7 @@
LOG_API(isolate, "ToString");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- str = i::Execution::ToString(obj, &has_pending_exception);
+ str = i::Execution::ToString(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
}
return ToApiHandle<String>(str);
@@ -2758,7 +2760,7 @@
LOG_API(isolate, "ToDetailString");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- str = i::Execution::ToDetailString(obj, &has_pending_exception);
+ str = i::Execution::ToDetailString(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
}
return ToApiHandle<String>(str);
@@ -2778,7 +2780,7 @@
LOG_API(isolate, "ToObject");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- val = i::Execution::ToObject(obj, &has_pending_exception);
+ val = i::Execution::ToObject(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
}
return ToApiHandle<Object>(val);
@@ -2816,7 +2818,7 @@
LOG_API(isolate, "ToNumber");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToNumber(obj, &has_pending_exception);
+ num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
}
return ToApiHandle<Number>(num);
@@ -2834,7 +2836,7 @@
LOG_API(isolate, "ToInteger");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToInteger(obj, &has_pending_exception);
+ num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
}
return ToApiHandle<Integer>(num);
@@ -2843,7 +2845,7 @@
void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
- ApiCheck(isolate != NULL && isolate->IsInitialized() && !i::V8::IsDead(),
+ ApiCheck(isolate != NULL && isolate->IsInitialized() && !isolate->IsDead(),
"v8::internal::Internals::CheckInitialized()",
"Isolate is not initialized or V8 has died");
}
@@ -3054,7 +3056,7 @@
LOG_API(isolate, "NumberValue");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToNumber(obj, &has_pending_exception);
+ num = i::Execution::ToNumber(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
}
return num->Number();
@@ -3072,7 +3074,7 @@
LOG_API(isolate, "IntegerValue");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToInteger(obj, &has_pending_exception);
+ num = i::Execution::ToInteger(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
}
if (num->IsSmi()) {
@@ -3094,7 +3096,7 @@
LOG_API(isolate, "ToInt32");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToInt32(obj, &has_pending_exception);
+ num = i::Execution::ToInt32(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
}
return ToApiHandle<Int32>(num);
@@ -3112,7 +3114,7 @@
LOG_API(isolate, "ToUInt32");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
- num = i::Execution::ToUint32(obj, &has_pending_exception);
+ num = i::Execution::ToUint32(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
}
return ToApiHandle<Uint32>(num);
@@ -3131,7 +3133,7 @@
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> string_obj =
- i::Execution::ToString(obj, &has_pending_exception);
+ i::Execution::ToString(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
uint32_t index;
@@ -3159,7 +3161,7 @@
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> num =
- i::Execution::ToInt32(obj, &has_pending_exception);
+ i::Execution::ToInt32(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
@@ -3240,7 +3242,7 @@
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> num =
- i::Execution::ToUint32(obj, &has_pending_exception);
+ i::Execution::ToUint32(isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, 0);
if (num->IsSmi()) {
return i::Smi::cast(*num)->value();
@@ -3377,7 +3379,7 @@
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
if (!key_obj->IsName()) {
EXCEPTION_PREAMBLE(isolate);
- key_obj = i::Execution::ToString(key_obj, &has_pending_exception);
+ key_obj = i::Execution::ToString(isolate, key_obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
}
i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
@@ -4079,7 +4081,7 @@
i::HandleScope scope(isolate);
i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
if (obj->IsJSFunction()) return true;
- return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
+ return i::Execution::GetFunctionDelegate(isolate, obj)->IsJSFunction();
}
@@ -4103,8 +4105,8 @@
fun = i::Handle<i::JSFunction>::cast(obj);
} else {
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> delegate =
- i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
+ i::Handle<i::Object> delegate = i::Execution::TryGetFunctionDelegate(
+ isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
fun = i::Handle<i::JSFunction>::cast(delegate);
recv_obj = obj;
@@ -4140,8 +4142,8 @@
i::Handle<i::JSObject>::cast(returned)));
}
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> delegate =
- i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
+ i::Handle<i::Object> delegate = i::Execution::TryGetConstructorDelegate(
+ isolate, obj, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
if (!delegate->IsUndefined()) {
i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
@@ -6050,7 +6052,7 @@
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj =
- i::Execution::NewDate(time, &has_pending_exception);
+ i::Execution::NewDate(isolate, time, &has_pending_exception);
EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
return Utils::ToLocal(obj);
}
@@ -7095,7 +7097,8 @@
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
ENTER_V8(isolate);
- isolate->debugger()->SetHostDispatchHandler(handler, period);
+ isolate->debugger()->SetHostDispatchHandler(
+ handler, i::TimeDelta::FromMilliseconds(period));
}
@@ -7169,7 +7172,7 @@
void Debug::ProcessDebugMessages() {
- i::Execution::ProcessDebugMessages(true);
+ i::Execution::ProcessDebugMessages(i::Isolate::Current(), true);
}
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index d9cc387..54530d8 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -61,7 +61,7 @@
// Print the code after compiling it.
static void PrintCode(Handle<Code> code, CompilationInfo* info);
- static bool ShouldGenerateLog(Expression* type);
+ static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
static void SetFunctionInfo(Handle<JSFunction> fun,
FunctionLiteral* lit,
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2a0d102..28ec1a2 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3312,7 +3312,7 @@
// 2 (array): Arguments to the format string.
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
+ if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
VisitForStackValue(args->at(1));
VisitForStackValue(args->at(2));
__ CallRuntime(Runtime::kLog, 2);
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 85c2a7c..ace134b 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -2588,8 +2588,8 @@
: isolate_(isolate),
active_(isolate->bootstrapper()) {
result_ = Handle<Context>::null();
- // If V8 isn't running and cannot be initialized, just return.
- if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
+ // 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.
diff --git a/src/builtins.cc b/src/builtins.cc
index f1ee0a4..fea503b 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1717,9 +1717,8 @@
}
-void Builtins::SetUp(bool create_heap_objects) {
+void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
ASSERT(!initialized_);
- Isolate* isolate = Isolate::Current();
Heap* heap = isolate->heap();
// Create a scope for the handles in the builtins.
diff --git a/src/builtins.h b/src/builtins.h
index a7c774a..b7be785 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -292,7 +292,7 @@
// Generate all builtin code objects. Should be called once during
// isolate initialization.
- void SetUp(bool create_heap_objects);
+ void SetUp(Isolate* isolate, bool create_heap_objects);
void TearDown();
// Garbage collection support.
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 35927f4..131fe31 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -217,8 +217,8 @@
template <class Stub>
class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
public:
- explicit CodeStubGraphBuilder(Stub* stub)
- : CodeStubGraphBuilderBase(Isolate::Current(), stub) {}
+ explicit CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
+ : CodeStubGraphBuilderBase(isolate, stub) {}
protected:
virtual HValue* BuildCodeStub() {
@@ -285,8 +285,7 @@
template <class Stub>
-static Handle<Code> DoGenerateCode(Stub* stub) {
- Isolate* isolate = Isolate::Current();
+static Handle<Code> DoGenerateCode(Isolate* isolate, Stub* stub) {
CodeStub::Major major_key =
static_cast<HydrogenCodeStub*>(stub)->MajorKey();
CodeStubInterfaceDescriptor* descriptor =
@@ -302,7 +301,7 @@
ASSERT(descriptor->stack_parameter_count_ == NULL);
return stub->GenerateLightweightMissCode(isolate);
}
- CodeStubGraphBuilder<Stub> builder(stub);
+ CodeStubGraphBuilder<Stub> builder(isolate, stub);
LChunk* chunk = OptimizeGraph(builder.CreateGraph());
return chunk->Codegen();
}
@@ -334,8 +333,8 @@
}
-Handle<Code> ToNumberStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -401,8 +400,8 @@
}
-Handle<Code> FastCloneShallowArrayStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> FastCloneShallowArrayStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -448,8 +447,8 @@
}
-Handle<Code> FastCloneShallowObjectStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> FastCloneShallowObjectStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -494,8 +493,8 @@
}
-Handle<Code> CreateAllocationSiteStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> CreateAllocationSiteStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -509,8 +508,8 @@
}
-Handle<Code> KeyedLoadFastElementStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> KeyedLoadFastElementStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -524,8 +523,8 @@
}
-Handle<Code> LoadFieldStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -539,8 +538,8 @@
}
-Handle<Code> KeyedLoadFieldStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -555,8 +554,8 @@
}
-Handle<Code> KeyedStoreFastElementStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> KeyedStoreFastElementStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -574,8 +573,8 @@
}
-Handle<Code> TransitionElementsKindStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> TransitionElementsKindStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
@@ -709,8 +708,8 @@
}
-Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -724,8 +723,9 @@
}
-Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode(
+ Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -738,8 +738,8 @@
}
-Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -751,8 +751,9 @@
}
-Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode(
+ Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -764,8 +765,9 @@
}
-Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode(
+ Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -777,8 +779,9 @@
}
-Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode(
+ Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -803,8 +806,8 @@
}
-Handle<Code> CompareNilICStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> CompareNilICStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -822,8 +825,8 @@
}
-Handle<Code> ToBooleanStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> ToBooleanStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -871,8 +874,8 @@
}
-Handle<Code> StoreGlobalStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> StoreGlobalStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -906,8 +909,8 @@
}
-Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> ElementsTransitionAndStoreStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
@@ -1096,8 +1099,8 @@
}
-Handle<Code> FastNewClosureStub::GenerateCode() {
- return DoGenerateCode(this);
+Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) {
+ return DoGenerateCode(isolate, this);
}
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 01456ee..6011275 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -46,7 +46,7 @@
function_mode_(NOT_JS_FUNCTION_STUB_MODE),
register_params_(NULL),
deoptimization_handler_(NULL),
- miss_handler_(IC_Utility(IC::kUnreachable), Isolate::Current()),
+ miss_handler_(),
has_miss_handler_(false) { }
@@ -93,8 +93,7 @@
}
-Handle<Code> PlatformCodeStub::GenerateCode() {
- Isolate* isolate = Isolate::Current();
+Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) {
Factory* factory = isolate->factory();
// Generate the new code.
@@ -144,7 +143,7 @@
{
HandleScope scope(isolate);
- Handle<Code> new_object = GenerateCode();
+ Handle<Code> new_object = GenerateCode(isolate);
new_object->set_major_key(MajorKey());
FinishCode(new_object);
RecordCodeGeneration(*new_object, isolate);
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 7c70583..4fe4e07 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -205,7 +205,7 @@
static bool CanUseFPRegisters();
// Generates the assembler code for the stub.
- virtual Handle<Code> GenerateCode() = 0;
+ virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
// Returns whether the code generated for this stub needs to be allocated as
@@ -263,7 +263,7 @@
class PlatformCodeStub : public CodeStub {
public:
// Retrieve the code for the stub. Generate the code if needed.
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
@@ -353,7 +353,7 @@
CodeStubInterfaceDescriptor* descriptor) = 0;
// Retrieve the code for the stub. Generate the code if needed.
- virtual Handle<Code> GenerateCode() = 0;
+ virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
virtual int NotMissMinorKey() = 0;
@@ -453,7 +453,7 @@
public:
ToNumberStub() { }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -471,7 +471,7 @@
: language_mode_(language_mode),
is_generator_(is_generator) { }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -539,7 +539,7 @@
IsConstantBits::encode(is_constant);
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -621,7 +621,7 @@
return LAST_ELEMENTS_KIND;
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -661,7 +661,7 @@
int length() const { return length_; }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -681,7 +681,7 @@
public:
explicit CreateAllocationSiteStub() { }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual bool IsPregenerated() { return true; }
@@ -898,7 +898,7 @@
Initialize(Code::LOAD_IC, inobject, index, representation);
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -967,7 +967,7 @@
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor);
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
private:
virtual CodeStub::Major MajorKey() { return KeyedLoadField; }
@@ -1238,7 +1238,7 @@
virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; }
- Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual Code::ExtraICState GetExtraICState() {
return NilValueField::encode(nil_value_) |
@@ -1763,7 +1763,7 @@
return ElementsKindBits::decode(bit_field_);
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -1803,7 +1803,7 @@
return StoreModeBits::decode(bit_field_);
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -1838,7 +1838,7 @@
return ToKindBits::decode(bit_field_);
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -1934,7 +1934,7 @@
: ArrayConstructorStubBase(kind, context_mode, override_mode) {
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -1956,7 +1956,7 @@
: ArrayConstructorStubBase(kind, context_mode, override_mode) {
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -1978,7 +1978,7 @@
: ArrayConstructorStubBase(kind, context_mode, override_mode) {
}
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -2021,7 +2021,7 @@
explicit InternalArrayNoArgumentConstructorStub(ElementsKind kind)
: InternalArrayConstructorStubBase(kind) { }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -2040,7 +2040,7 @@
explicit InternalArraySingleArgumentConstructorStub(ElementsKind kind)
: InternalArrayConstructorStubBase(kind) { }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -2059,7 +2059,7 @@
explicit InternalArrayNArgumentsConstructorStub(ElementsKind kind)
: InternalArrayConstructorStubBase(kind) { }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
@@ -2148,7 +2148,7 @@
bool UpdateStatus(Handle<Object> object);
Types GetTypes() { return types_; }
- virtual Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
virtual void InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor);
@@ -2208,7 +2208,7 @@
bool is_jsarray() const { return is_jsarray_; }
KeyedAccessStoreMode store_mode() const { return store_mode_; }
- Handle<Code> GenerateCode();
+ virtual Handle<Code> GenerateCode(Isolate* isolate);
void InitializeInterfaceDescriptor(
Isolate* isolate,
diff --git a/src/codegen.cc b/src/codegen.cc
index 6ec3751..d33c7f0 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -124,7 +124,7 @@
void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
#ifdef ENABLE_DISASSEMBLER
AllowDeferredHandleDereference allow_deference_for_print_code;
- bool print_code = Isolate::Current()->bootstrapper()->IsActive()
+ bool print_code = info->isolate()->bootstrapper()->IsActive()
? FLAG_print_builtin_code
: (FLAG_print_code ||
(info->IsStub() && FLAG_print_code_stubs) ||
@@ -171,9 +171,8 @@
}
-bool CodeGenerator::ShouldGenerateLog(Expression* type) {
+bool CodeGenerator::ShouldGenerateLog(Isolate* isolate, Expression* type) {
ASSERT(type != NULL);
- Isolate* isolate = Isolate::Current();
if (!isolate->logger()->is_logging() &&
!isolate->cpu_profiler()->is_profiling()) {
return false;
diff --git a/src/compiler.cc b/src/compiler.cc
index 1fba20f..bc65b1f 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -119,7 +119,7 @@
mode_ = STUB;
return;
}
- mode_ = V8::UseCrankshaft() ? mode : NONOPT;
+ mode_ = isolate->use_crankshaft() ? mode : NONOPT;
abort_due_to_dependency_ = false;
if (script_->type()->value() == Script::TYPE_NATIVE) {
MarkAsNative();
@@ -242,7 +242,7 @@
// break points has actually been set.
static bool IsDebuggerActive(Isolate* isolate) {
#ifdef ENABLE_DEBUGGER_SUPPORT
- return V8::UseCrankshaft() ?
+ return isolate->use_crankshaft() ?
isolate->debug()->has_break_points() :
isolate->debugger()->IsDebuggerActive();
#else
@@ -310,7 +310,7 @@
OptimizingCompiler::Status OptimizingCompiler::CreateGraph() {
- ASSERT(V8::UseCrankshaft());
+ ASSERT(isolate()->use_crankshaft());
ASSERT(info()->IsOptimizing());
ASSERT(!info()->IsCompilingForDebugging());
@@ -499,7 +499,7 @@
static bool GenerateCode(CompilationInfo* info) {
- bool is_optimizing = V8::UseCrankshaft() &&
+ bool is_optimizing = info->isolate()->use_crankshaft() &&
!info->IsCompilingForDebugging() &&
info->IsOptimizing();
if (is_optimizing) {
@@ -838,14 +838,14 @@
shared->set_dont_inline(lit->flags()->Contains(kDontInline));
shared->set_ast_node_count(lit->ast_node_count());
- if (V8::UseCrankshaft() &&
+ if (info->isolate()->use_crankshaft() &&
!function.is_null() &&
!shared->optimization_disabled()) {
// If we're asked to always optimize, we compile the optimized
// version of the function right away - unless the debugger is
// active as it makes no sense to compile optimized code then.
if (FLAG_always_opt &&
- !Isolate::Current()->DebuggerHasBreakPoints()) {
+ !info->isolate()->DebuggerHasBreakPoints()) {
CompilationInfoWithZone optimized(function);
optimized.SetOptimizing(BailoutId::None());
return Compiler::CompileLazy(&optimized);
diff --git a/src/compiler.h b/src/compiler.h
index bdb168f..4f6a472 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -335,7 +335,7 @@
void Initialize(Isolate* isolate, Mode mode, Zone* zone);
void SetMode(Mode mode) {
- ASSERT(V8::UseCrankshaft());
+ ASSERT(isolate()->use_crankshaft());
mode_ = mode;
}
diff --git a/src/contexts.cc b/src/contexts.cc
index 0fddfdf..5981fd6 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -74,7 +74,7 @@
// During bootstrapping, the global object might not be set and we
// have to search the context chain to find the native context.
- ASSERT(Isolate::Current()->bootstrapper()->IsActive());
+ ASSERT(this->GetIsolate()->bootstrapper()->IsActive());
Context* current = this;
while (!current->IsNativeContext()) {
JSFunction* closure = JSFunction::cast(current->closure());
@@ -352,10 +352,9 @@
}
-bool Context::IsBootstrappingOrGlobalObject(Object* object) {
+bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) {
// During bootstrapping we allow all objects to pass as global
// objects. This is necessary to fix circular dependencies.
- Isolate* isolate = Isolate::Current();
return isolate->heap()->gc_state() != Heap::NOT_IN_GC ||
isolate->bootstrapper()->IsActive() ||
object->IsGlobalObject();
diff --git a/src/contexts.h b/src/contexts.h
index fdf6d27..88c3cd9 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -370,7 +370,7 @@
GlobalObject* global_object() {
Object* result = get(GLOBAL_OBJECT_INDEX);
- ASSERT(IsBootstrappingOrGlobalObject(result));
+ ASSERT(IsBootstrappingOrGlobalObject(this->GetIsolate(), result));
return reinterpret_cast<GlobalObject*>(result);
}
void set_global_object(GlobalObject* object) {
@@ -508,7 +508,7 @@
#ifdef DEBUG
// Bootstrapping-aware type checks.
static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
- static bool IsBootstrappingOrGlobalObject(Object* object);
+ static bool IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object);
#endif
STATIC_CHECK(kHeaderSize == Internals::kContextHeaderSize);
diff --git a/src/counters.cc b/src/counters.cc
index e2530a8..e0a6a60 100644
--- a/src/counters.cc
+++ b/src/counters.cc
@@ -41,7 +41,7 @@
int* StatsCounter::FindLocationInStatsTable() const {
- return Isolate::Current()->stats_table()->FindLocation(name_);
+ return isolate_->stats_table()->FindLocation(name_);
}
diff --git a/src/counters.h b/src/counters.h
index 8cfe6c5..93911d7 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -116,8 +116,8 @@
class StatsCounter {
public:
StatsCounter() { }
- explicit StatsCounter(const char* name)
- : name_(name), ptr_(NULL), lookup_done_(false) { }
+ explicit StatsCounter(Isolate* isolate, const char* name)
+ : isolate_(isolate), name_(name), ptr_(NULL), lookup_done_(false) { }
// Sets the counter to a specific value.
void Set(int value) {
@@ -175,6 +175,7 @@
private:
int* FindLocationInStatsTable() const;
+ Isolate* isolate_;
const char* name_;
int* ptr_;
bool lookup_done_;
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index 3adeb71..2905500 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -201,7 +201,7 @@
// Process events received from debugged VM and from the keyboard.
bool terminate = false;
while (!terminate) {
- event_available_->Wait();
+ event_available_.Wait();
RemoteDebuggerEvent* event = GetEvent();
switch (event->type()) {
case RemoteDebuggerEvent::kMessage:
@@ -258,7 +258,7 @@
tail_->set_next(event);
tail_ = event;
}
- event_available_->Signal();
+ event_available_.Signal();
}
diff --git a/src/d8-debug.h b/src/d8-debug.h
index 276cbd8..5587622 100644
--- a/src/d8-debug.h
+++ b/src/d8-debug.h
@@ -53,7 +53,7 @@
explicit RemoteDebugger(Isolate* isolate, int port)
: isolate_(isolate),
port_(port),
- event_available_(i::OS::CreateSemaphore(0)),
+ event_available_(0),
head_(NULL), tail_(NULL) {}
void Run();
@@ -84,7 +84,7 @@
// the list is guarded by a mutex and a semaphore signals new items in the
// list.
i::Mutex event_access_;
- i::Semaphore* event_available_;
+ i::Semaphore event_available_;
RemoteDebuggerEvent* head_;
RemoteDebuggerEvent* tail_;
diff --git a/src/d8.cc b/src/d8.cc
index 4a10550..ea8b875 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -271,10 +271,10 @@
PerIsolateData::RealmScope::~RealmScope() {
// Drop realms to avoid keeping them alive.
for (int i = 0; i < data_->realm_count_; ++i)
- data_->realms_[i].Dispose(data_->isolate_);
+ data_->realms_[i].Dispose();
delete[] data_->realms_;
if (!data_->realm_shared_.IsEmpty())
- data_->realm_shared_.Dispose(data_->isolate_);
+ data_->realm_shared_.Dispose();
}
@@ -361,7 +361,7 @@
Throw("Invalid realm index");
return;
}
- data->realms_[index].Dispose(isolate);
+ data->realms_[index].Dispose();
data->realms_[index].Clear();
}
@@ -420,7 +420,7 @@
const PropertyCallbackInfo<void>& info) {
Isolate* isolate = info.GetIsolate();
PerIsolateData* data = PerIsolateData::Get(isolate);
- if (!data->realm_shared_.IsEmpty()) data->realm_shared_.Dispose(isolate);
+ if (!data->realm_shared_.IsEmpty()) data->realm_shared_.Dispose();
data->realm_shared_.Reset(isolate, value);
}
@@ -766,7 +766,7 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
// Install the debugger object in the utility scope
- i::Debug* debug = i::Isolate::Current()->debug();
+ i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
debug->Load();
i::Handle<i::JSObject> js_debug
= i::Handle<i::JSObject>(debug->debug_context()->global_object());
@@ -935,7 +935,7 @@
Context::Scope scope(context);
#ifndef V8_SHARED
- i::Factory* factory = i::Isolate::Current()->factory();
+ i::Factory* factory = reinterpret_cast<i::Isolate*>(isolate)->factory();
i::JSArguments js_args = i::FLAG_js_arguments;
i::Handle<i::FixedArray> arguments_array =
factory->NewFixedArray(js_args.argc());
@@ -1220,10 +1220,6 @@
SourceGroup::~SourceGroup() {
#ifndef V8_SHARED
- delete next_semaphore_;
- next_semaphore_ = NULL;
- delete done_semaphore_;
- done_semaphore_ = NULL;
delete thread_;
thread_ = NULL;
#endif // V8_SHARED
@@ -1284,7 +1280,7 @@
void SourceGroup::ExecuteInThread() {
Isolate* isolate = Isolate::New();
do {
- if (next_semaphore_ != NULL) next_semaphore_->Wait();
+ next_semaphore_.Wait();
{
Isolate::Scope iscope(isolate);
Locker lock(isolate);
@@ -1304,7 +1300,7 @@
V8::IdleNotification(kLongIdlePauseInMs);
}
}
- if (done_semaphore_ != NULL) done_semaphore_->Signal();
+ done_semaphore_.Signal();
} while (!Shell::options.last_run);
isolate->Dispose();
}
@@ -1315,7 +1311,7 @@
thread_ = new IsolateThread(this);
thread_->Start();
}
- next_semaphore_->Signal();
+ next_semaphore_.Signal();
}
@@ -1324,7 +1320,7 @@
if (Shell::options.last_run) {
thread_->Join();
} else {
- done_semaphore_->Wait();
+ done_semaphore_.Wait();
}
}
#endif // V8_SHARED
diff --git a/src/d8.h b/src/d8.h
index fbc7a10..1ae1bcf 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -140,8 +140,8 @@
public:
SourceGroup() :
#ifndef V8_SHARED
- next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
- done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
+ next_semaphore_(0),
+ done_semaphore_(0),
thread_(NULL),
#endif // V8_SHARED
argv_(NULL),
@@ -180,8 +180,8 @@
static i::Thread::Options GetThreadOptions();
void ExecuteInThread();
- i::Semaphore* next_semaphore_;
- i::Semaphore* done_semaphore_;
+ i::Semaphore next_semaphore_;
+ i::Semaphore done_semaphore_;
i::Thread* thread_;
#endif // V8_SHARED
diff --git a/src/debug-agent.cc b/src/debug-agent.cc
index b390cc5..51bd4b1 100644
--- a/src/debug-agent.cc
+++ b/src/debug-agent.cc
@@ -46,8 +46,6 @@
// Debugger agent main thread.
void DebuggerAgent::Run() {
- const int kOneSecondInMicros = 1000000;
-
// Allow this socket to reuse port even if still in TIME_WAIT.
server_->SetReuseAddress(true);
@@ -60,16 +58,20 @@
// would be that the port is already in use so this avoids a busy loop and
// make the agent take over the port when it becomes free.
if (!bound) {
+ const TimeDelta kTimeout = TimeDelta::FromSeconds(1);
PrintF("Failed to open socket on port %d, "
- "waiting %d ms before retrying\n", port_, kOneSecondInMicros / 1000);
- terminate_now_->Wait(kOneSecondInMicros);
+ "waiting %d ms before retrying\n", port_,
+ static_cast<int>(kTimeout.InMilliseconds()));
+ if (!terminate_now_.WaitFor(kTimeout)) {
+ if (terminate_) return;
+ }
}
}
// Accept connections on the bound port.
while (!terminate_) {
bool ok = server_->Listen(1);
- listening_->Signal();
+ listening_.Signal();
if (ok) {
// Accept the new connection.
Socket* client = server_->Accept();
@@ -89,7 +91,7 @@
// Signal termination and make the server exit either its listen call or its
// binding loop. This makes sure that no new sessions can be established.
- terminate_now_->Signal();
+ terminate_now_.Signal();
server_->Shutdown();
Join();
@@ -99,7 +101,7 @@
void DebuggerAgent::WaitUntilListening() {
- listening_->Wait();
+ listening_.Wait();
}
static const char* kCreateSessionMessage =
diff --git a/src/debug-agent.h b/src/debug-agent.h
index e78ed67..9d7c62b 100644
--- a/src/debug-agent.h
+++ b/src/debug-agent.h
@@ -43,14 +43,14 @@
// handles connection from a remote debugger.
class DebuggerAgent: public Thread {
public:
- DebuggerAgent(const char* name, int port)
+ DebuggerAgent(Isolate* isolate, const char* name, int port)
: Thread(name),
- isolate_(Isolate::Current()),
+ isolate_(isolate),
name_(StrDup(name)), port_(port),
server_(OS::CreateSocket()), terminate_(false),
session_(NULL),
- terminate_now_(OS::CreateSemaphore(0)),
- listening_(OS::CreateSemaphore(0)) {
+ terminate_now_(0),
+ listening_(0) {
ASSERT(isolate_->debugger_agent_instance() == NULL);
isolate_->set_debugger_agent_instance(this);
}
@@ -78,8 +78,8 @@
bool terminate_; // Termination flag.
RecursiveMutex session_access_; // Mutex guarding access to session_.
DebuggerAgentSession* session_; // Current active session if any.
- Semaphore* terminate_now_; // Semaphore to signal termination.
- Semaphore* listening_;
+ Semaphore terminate_now_; // Semaphore to signal termination.
+ Semaphore listening_;
friend class DebuggerAgentSession;
friend void DebuggerAgentMessageHandler(const v8::Debug::Message& message);
diff --git a/src/debug.cc b/src/debug.cc
index dfe7b97..9f38601 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -86,8 +86,9 @@
}
-static Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) {
- Isolate* isolate = Isolate::Current();
+static Handle<Code> ComputeCallDebugPrepareStepIn(Isolate* isolate,
+ int argc,
+ Code::Kind kind) {
return isolate->stub_cache()->ComputeCallDebugPrepareStepIn(argc, kind);
}
@@ -403,11 +404,11 @@
bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) {
- if (RelocInfo::IsConstructCall(rmode())) {
+ if (RelocInfo::IsConstructCall(original_rmode())) {
return true;
} else if (RelocInfo::IsCodeTarget(rmode())) {
HandleScope scope(debug_info_->GetIsolate());
- Address target = rinfo()->target_address();
+ Address target = original_rinfo()->target_address();
Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
if (target_code->kind() == Code::STUB) {
return target_code->major_key() == CodeStub::CallFunction;
@@ -433,7 +434,7 @@
// the call in the original code as it is the code there that will be
// executed in place of the debug break call.
Handle<Code> stub = ComputeCallDebugPrepareStepIn(
- target_code->arguments_count(), target_code->kind());
+ isolate, target_code->arguments_count(), target_code->kind());
if (IsDebugBreak()) {
original_rinfo()->set_target_address(stub->entry());
} else {
@@ -633,7 +634,7 @@
void ScriptCache::Add(Handle<Script> script) {
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
+ GlobalHandles* global_handles = isolate_->global_handles();
// Create an entry in the hash map for the script.
int id = script->id()->value();
HashMap::Entry* entry =
@@ -655,7 +656,7 @@
Handle<FixedArray> ScriptCache::GetScripts() {
- Factory* factory = Isolate::Current()->factory();
+ Factory* factory = isolate_->factory();
Handle<FixedArray> instances = factory->NewFixedArray(occupancy());
int count = 0;
for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
@@ -670,7 +671,7 @@
void ScriptCache::ProcessCollectedScripts() {
- Debugger* debugger = Isolate::Current()->debugger();
+ Debugger* debugger = isolate_->debugger();
for (int i = 0; i < collected_scripts_.length(); i++) {
debugger->OnScriptCollected(collected_scripts_[i]);
}
@@ -679,7 +680,7 @@
void ScriptCache::Clear() {
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
+ GlobalHandles* global_handles = isolate_->global_handles();
// Iterate the script cache to get rid of all the weak handles.
for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
ASSERT(entry != NULL);
@@ -708,7 +709,7 @@
script_cache->collected_scripts_.Add(id);
// Clear the weak handle.
- obj->Dispose(isolate);
+ obj->Dispose();
}
@@ -750,7 +751,7 @@
DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
+ GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
// Globalize the request debug info object and make it weak.
debug_info_ = Handle<DebugInfo>::cast(
(global_handles->Create(debug_info)));
@@ -761,13 +762,12 @@
DebugInfoListNode::~DebugInfoListNode() {
- Isolate::Current()->global_handles()->Destroy(
+ debug_info_->GetIsolate()->global_handles()->Destroy(
reinterpret_cast<Object**>(debug_info_.location()));
}
-bool Debug::CompileDebuggerScript(int index) {
- Isolate* isolate = Isolate::Current();
+bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
Factory* factory = isolate->factory();
HandleScope scope(isolate);
@@ -824,7 +824,7 @@
ASSERT(!isolate->has_pending_exception());
if (!exception.is_null()) {
isolate->set_pending_exception(*exception);
- MessageHandler::ReportMessage(Isolate::Current(), NULL, message);
+ MessageHandler::ReportMessage(isolate, NULL, message);
isolate->clear_pending_exception();
}
return false;
@@ -852,7 +852,7 @@
// Disable breakpoints and interrupts while compiling and running the
// debugger scripts including the context creation code.
- DisableBreak disable(true);
+ DisableBreak disable(isolate_, true);
PostponeInterruptsScope postpone(isolate_);
// Create the debugger context.
@@ -886,12 +886,12 @@
// Compile the JavaScript for the debugger in the debugger context.
debugger->set_compiling_natives(true);
bool caught_exception =
- !CompileDebuggerScript(Natives::GetIndex("mirror")) ||
- !CompileDebuggerScript(Natives::GetIndex("debug"));
+ !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) ||
+ !CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
if (FLAG_enable_liveedit) {
caught_exception = caught_exception ||
- !CompileDebuggerScript(Natives::GetIndex("liveedit"));
+ !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
}
debugger->set_compiling_natives(false);
@@ -958,7 +958,7 @@
}
// Enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) {
return heap->undefined_value();
}
@@ -1649,7 +1649,7 @@
// Find the builtin to use for invoking the debug break
Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = code->GetIsolate();
// Find the builtin debug break function matching the calling convention
// used by the call site.
@@ -1704,7 +1704,7 @@
Handle<Object> Debug::GetSourceBreakLocations(
Handle<SharedFunctionInfo> shared,
BreakPositionAlignment position_alignment) {
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = shared->GetIsolate();
Heap* heap = isolate->heap();
if (!HasDebugInfo(shared)) {
return Handle<Object>(heap->undefined_value(), isolate);
@@ -1883,7 +1883,7 @@
// Use compile lazy which will end up compiling the full code in the
// configuration configured above.
bool result = Compiler::CompileLazy(&info);
- ASSERT(result != Isolate::Current()->has_pending_exception());
+ ASSERT(result != info.isolate()->has_pending_exception());
info.isolate()->clear_pending_exception();
#if DEBUG
if (result) {
@@ -2537,7 +2537,7 @@
"Debug::CreateScriptCache");
ASSERT(script_cache_ == NULL);
- script_cache_ = new ScriptCache();
+ script_cache_ = new ScriptCache(isolate_);
// Scan heap for Script objects.
int count = 0;
@@ -2614,19 +2614,16 @@
host_dispatch_handler_(NULL),
debug_message_dispatch_handler_(NULL),
message_dispatch_helper_thread_(NULL),
- host_dispatch_micros_(100 * 1000),
+ host_dispatch_period_(TimeDelta::FromMilliseconds(100)),
agent_(NULL),
command_queue_(isolate->logger(), kQueueInitialSize),
- command_received_(OS::CreateSemaphore(0)),
+ command_received_(0),
event_command_queue_(isolate->logger(), kQueueInitialSize),
isolate_(isolate) {
}
-Debugger::~Debugger() {
- delete command_received_;
- command_received_ = 0;
-}
+Debugger::~Debugger() {}
Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
@@ -2757,7 +2754,7 @@
}
// Enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) return;
// Clear all current stepping setup.
@@ -2823,7 +2820,7 @@
if (!EventActive(v8::BeforeCompile)) return;
// Enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) return;
// Create the event data object.
@@ -2860,7 +2857,7 @@
bool in_debugger = debug->InDebugger();
// Enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) return;
// If debugging there might be script break points registered for this
@@ -2888,7 +2885,7 @@
bool caught_exception;
Handle<Object> argv[] = { wrapper };
Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
- Isolate::Current()->js_builtins_object(),
+ isolate_->js_builtins_object(),
ARRAY_SIZE(argv),
argv,
&caught_exception);
@@ -2923,7 +2920,7 @@
if (!Debugger::EventActive(v8::ScriptCollected)) return;
// Enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) return;
// Create the script collected state object.
@@ -3040,7 +3037,7 @@
Handle<Context> Debugger::GetDebugContext() {
never_unload_debugger_ = true;
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
return isolate_->debug()->debug_context();
}
@@ -3149,14 +3146,14 @@
// Wait for new command in the queue.
if (Debugger::host_dispatch_handler_) {
// In case there is a host dispatch - do periodic dispatches.
- if (!command_received_->Wait(host_dispatch_micros_)) {
+ if (!command_received_.WaitFor(host_dispatch_period_)) {
// Timout expired, do the dispatch.
Debugger::host_dispatch_handler_();
continue;
}
} else {
// In case there is no host dispatch - just wait.
- command_received_->Wait();
+ command_received_.Wait();
}
// Get the command from the queue.
@@ -3298,9 +3295,9 @@
void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
- int period) {
+ TimeDelta period) {
host_dispatch_handler_ = handler;
- host_dispatch_micros_ = period * 1000;
+ host_dispatch_period_ = period;
}
@@ -3340,7 +3337,7 @@
client_data);
isolate_->logger()->DebugTag("Put command on command_queue.");
command_queue_.Put(message);
- command_received_->Signal();
+ command_received_.Signal();
// Set the debug command break flag to have the command processed.
if (!isolate_->debug()->InDebugger()) {
@@ -3393,7 +3390,7 @@
Debugger::never_unload_debugger_ = true;
// Enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) {
return isolate_->factory()->undefined_value();
}
@@ -3438,7 +3435,7 @@
if (Socket::SetUp()) {
if (agent_ == NULL) {
- agent_ = new DebuggerAgent(name, port);
+ agent_ = new DebuggerAgent(isolate_, name, port);
agent_->Start();
}
return true;
@@ -3478,8 +3475,8 @@
}
-EnterDebugger::EnterDebugger()
- : isolate_(Isolate::Current()),
+EnterDebugger::EnterDebugger(Isolate* isolate)
+ : isolate_(isolate),
prev_(isolate_->debug()->debugger_entry()),
it_(isolate_),
has_js_frames_(!it_.done()),
@@ -3659,7 +3656,7 @@
v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = event_data_->GetIsolate();
v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
// Isolate::context() may be NULL when "script collected" event occures.
ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected);
@@ -3700,7 +3697,7 @@
v8::Handle<v8::Context> EventDetailsImpl::GetEventContext() const {
- return GetDebugEventContext(Isolate::Current());
+ return GetDebugEventContext(exec_state_->GetIsolate());
}
@@ -3822,16 +3819,11 @@
MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate)
: Thread("v8:MsgDispHelpr"),
- isolate_(isolate), sem_(OS::CreateSemaphore(0)),
+ isolate_(isolate), sem_(0),
already_signalled_(false) {
}
-MessageDispatchHelperThread::~MessageDispatchHelperThread() {
- delete sem_;
-}
-
-
void MessageDispatchHelperThread::Schedule() {
{
LockGuard<Mutex> lock_guard(&mutex_);
@@ -3840,13 +3832,13 @@
}
already_signalled_ = true;
}
- sem_->Signal();
+ sem_.Signal();
}
void MessageDispatchHelperThread::Run() {
while (true) {
- sem_->Wait();
+ sem_.Wait();
{
LockGuard<Mutex> lock_guard(&mutex_);
already_signalled_ = false;
diff --git a/src/debug.h b/src/debug.h
index 2333b07..0c24b90 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -174,7 +174,8 @@
// the cache is the script id.
class ScriptCache : private HashMap {
public:
- ScriptCache() : HashMap(ScriptMatch), collected_scripts_(10) {}
+ explicit ScriptCache(Isolate* isolate)
+ : HashMap(ScriptMatch), isolate_(isolate), collected_scripts_(10) {}
virtual ~ScriptCache() { Clear(); }
// Add script to the cache.
@@ -203,6 +204,7 @@
v8::Persistent<v8::Value>* obj,
void* data);
+ Isolate* isolate_;
// List used during GC to temporarily store id's of collected scripts.
List<int> collected_scripts_;
};
@@ -532,7 +534,7 @@
explicit Debug(Isolate* isolate);
~Debug();
- static bool CompileDebuggerScript(int index);
+ static bool CompileDebuggerScript(Isolate* isolate, int index);
void ClearOneShot();
void ActivateStepIn(StackFrame* frame);
void ClearStepIn();
@@ -820,7 +822,7 @@
void SetEventListener(Handle<Object> callback, Handle<Object> data);
void SetMessageHandler(v8::Debug::MessageHandler2 handler);
void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
- int period);
+ TimeDelta period);
void SetDebugMessageDispatchHandler(
v8::Debug::DebugMessageDispatchHandler handler,
bool provide_locker);
@@ -931,13 +933,13 @@
Mutex dispatch_handler_access_; // Mutex guarding dispatch handler.
v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_;
MessageDispatchHelperThread* message_dispatch_helper_thread_;
- int host_dispatch_micros_;
+ TimeDelta host_dispatch_period_;
DebuggerAgent* agent_;
static const int kQueueInitialSize = 4;
LockingCommandMessageQueue command_queue_;
- Semaphore* command_received_; // Signaled for each command received.
+ Semaphore command_received_; // Signaled for each command received.
LockingCommandMessageQueue event_command_queue_;
Isolate* isolate_;
@@ -955,7 +957,7 @@
// some reason could not be entered FailedToEnter will return true.
class EnterDebugger BASE_EMBEDDED {
public:
- EnterDebugger();
+ explicit EnterDebugger(Isolate* isolate);
~EnterDebugger();
// Check whether the debugger could be entered.
@@ -982,7 +984,8 @@
// Stack allocated class for disabling break.
class DisableBreak BASE_EMBEDDED {
public:
- explicit DisableBreak(bool disable_break) : isolate_(Isolate::Current()) {
+ explicit DisableBreak(Isolate* isolate, bool disable_break)
+ : isolate_(isolate) {
prev_disable_break_ = isolate_->debug()->disable_break();
isolate_->debug()->set_disable_break(disable_break);
}
@@ -1046,7 +1049,7 @@
class MessageDispatchHelperThread: public Thread {
public:
explicit MessageDispatchHelperThread(Isolate* isolate);
- ~MessageDispatchHelperThread();
+ ~MessageDispatchHelperThread() {}
void Schedule();
@@ -1054,7 +1057,7 @@
void Run();
Isolate* isolate_;
- Semaphore* const sem_;
+ Semaphore sem_;
Mutex mutex_;
bool already_signalled_;
diff --git a/src/disassembler.cc b/src/disassembler.cc
index fa8ae1f..55b4127 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -71,7 +71,7 @@
const char* V8NameConverter::NameOfAddress(byte* pc) const {
- const char* name = Isolate::Current()->builtins()->Lookup(pc);
+ const char* name = code_->GetIsolate()->builtins()->Lookup(pc);
if (name != NULL) {
OS::SNPrintF(v8_buffer_, "%s (%p)", name, pc);
return v8_buffer_.start();
diff --git a/src/elements.cc b/src/elements.cc
index 5cef12b..3e864f4 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -492,7 +492,6 @@
}
StackFrame* raw_frame = it.frame();
if (raw_frame->is_internal()) {
- Isolate* isolate = Isolate::Current();
Code* apply_builtin = isolate->builtins()->builtin(
Builtins::kFunctionApply);
if (raw_frame->unchecked_code() == apply_builtin) {
diff --git a/src/execution.cc b/src/execution.cc
index ecfa1db..6075624 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -156,8 +156,9 @@
bool convert_receiver) {
*pending_exception = false;
+ Isolate* isolate = Isolate::Current();
if (!callable->IsJSFunction()) {
- callable = TryGetFunctionDelegate(callable, pending_exception);
+ callable = TryGetFunctionDelegate(isolate, callable, pending_exception);
if (*pending_exception) return callable;
}
Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
@@ -174,7 +175,7 @@
receiver = Handle<Object>(global, func->GetIsolate());
}
} else {
- receiver = ToObject(receiver, pending_exception);
+ receiver = ToObject(isolate, receiver, pending_exception);
}
if (*pending_exception) return callable;
}
@@ -234,9 +235,9 @@
}
-Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
+Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
+ Handle<Object> object) {
ASSERT(!object->IsJSFunction());
- Isolate* isolate = Isolate::Current();
Factory* factory = isolate->factory();
// If you return a function from here, it will be called when an
@@ -261,10 +262,10 @@
}
-Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
+Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
+ Handle<Object> object,
bool* has_pending_exception) {
ASSERT(!object->IsJSFunction());
- Isolate* isolate = Isolate::Current();
// If object is a function proxy, get its handler. Iterate if necessary.
Object* fun = *object;
@@ -292,9 +293,9 @@
}
-Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
+Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
+ Handle<Object> object) {
ASSERT(!object->IsJSFunction());
- Isolate* isolate = Isolate::Current();
// If you return a function from here, it will be called when an
// attempt is made to call the given object as a constructor.
@@ -319,10 +320,10 @@
Handle<Object> Execution::TryGetConstructorDelegate(
+ Isolate* isolate,
Handle<Object> object,
bool* has_pending_exception) {
ASSERT(!object->IsJSFunction());
- Isolate* isolate = Isolate::Current();
// If you return a function from here, it will be called when an
// attempt is made to call the given object as a constructor.
@@ -596,7 +597,6 @@
#define RETURN_NATIVE_CALL(name, args, has_pending_exception) \
do { \
- Isolate* isolate = Isolate::Current(); \
Handle<Object> argv[] = args; \
ASSERT(has_pending_exception != NULL); \
return Call(isolate->name##_fun(), \
@@ -606,44 +606,50 @@
} while (false)
-Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToNumber(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
RETURN_NATIVE_CALL(to_number, { obj }, exc);
}
-Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToString(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
RETURN_NATIVE_CALL(to_string, { obj }, exc);
}
-Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToDetailString(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
}
-Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToObject(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
if (obj->IsSpecObject()) return obj;
RETURN_NATIVE_CALL(to_object, { obj }, exc);
}
-Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToInteger(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
RETURN_NATIVE_CALL(to_integer, { obj }, exc);
}
-Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToUint32(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
}
-Handle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) {
+Handle<Object> Execution::ToInt32(
+ Isolate* isolate, Handle<Object> obj, bool* exc) {
RETURN_NATIVE_CALL(to_int32, { obj }, exc);
}
-Handle<Object> Execution::NewDate(double time, bool* exc) {
- Isolate* isolate = Isolate::Current();
+Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) {
Handle<Object> time_obj = isolate->factory()->NewNumber(time);
RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
}
@@ -749,10 +755,10 @@
}
-void Execution::ConfigureInstance(Handle<Object> instance,
+void Execution::ConfigureInstance(Isolate* isolate,
+ Handle<Object> instance,
Handle<Object> instance_template,
bool* exc) {
- Isolate* isolate = Isolate::Current();
Handle<Object> args[] = { instance, instance_template };
Execution::Call(isolate->configure_instance_fun(),
isolate->js_builtins_object(),
@@ -782,9 +788,7 @@
}
-static Object* RuntimePreempt() {
- Isolate* isolate = Isolate::Current();
-
+static Object* RuntimePreempt(Isolate* isolate) {
// Clear the preempt request flag.
isolate->stack_guard()->Continue(PREEMPT);
@@ -813,9 +817,7 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
-Object* Execution::DebugBreakHelper() {
- Isolate* isolate = Isolate::Current();
-
+Object* Execution::DebugBreakHelper(Isolate* isolate) {
// Just continue if breaks are disabled.
if (isolate->debug()->disable_break()) {
return isolate->heap()->undefined_value();
@@ -861,15 +863,15 @@
// Clear the debug break request flag.
isolate->stack_guard()->Continue(DEBUGBREAK);
- ProcessDebugMessages(debug_command_only);
+ ProcessDebugMessages(isolate, debug_command_only);
// Return to continue execution.
return isolate->heap()->undefined_value();
}
-void Execution::ProcessDebugMessages(bool debug_command_only) {
- Isolate* isolate = Isolate::Current();
+void Execution::ProcessDebugMessages(Isolate* isolate,
+ bool debug_command_only) {
// Clear the debug command request flag.
isolate->stack_guard()->Continue(DEBUGCOMMAND);
@@ -880,7 +882,7 @@
HandleScope scope(isolate);
// Enter the debugger. Just continue if we fail to enter the debugger.
- EnterDebugger debugger;
+ EnterDebugger debugger(isolate);
if (debugger.FailedToEnter()) {
return;
}
@@ -911,10 +913,10 @@
isolate->runtime_profiler()->OptimizeNow();
#ifdef ENABLE_DEBUGGER_SUPPORT
if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
- DebugBreakHelper();
+ DebugBreakHelper(isolate);
}
#endif
- if (stack_guard->IsPreempted()) RuntimePreempt();
+ if (stack_guard->IsPreempted()) RuntimePreempt(isolate);
if (stack_guard->IsTerminateExecution()) {
stack_guard->Continue(TERMINATE);
return isolate->TerminateExecution();
diff --git a/src/execution.h b/src/execution.h
index c6bf63d..1a9a66c 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -92,28 +92,36 @@
bool* caught_exception);
// ECMA-262 9.3
- static Handle<Object> ToNumber(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToNumber(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// ECMA-262 9.4
- static Handle<Object> ToInteger(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToInteger(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// ECMA-262 9.5
- static Handle<Object> ToInt32(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToInt32(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// ECMA-262 9.6
- static Handle<Object> ToUint32(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToUint32(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// ECMA-262 9.8
- static Handle<Object> ToString(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToString(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// ECMA-262 9.8
- static Handle<Object> ToDetailString(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToDetailString(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// ECMA-262 9.9
- static Handle<Object> ToObject(Handle<Object> obj, bool* exc);
+ static Handle<Object> ToObject(
+ Isolate* isolate, Handle<Object> obj, bool* exc);
// Create a new date object from 'time'.
- static Handle<Object> NewDate(double time, bool* exc);
+ static Handle<Object> NewDate(
+ Isolate* isolate, double time, bool* exc);
// Create a new regular expression object from 'pattern' and 'flags'.
static Handle<JSRegExp> NewJSRegExp(Handle<String> pattern,
@@ -128,7 +136,8 @@
Handle<FunctionTemplateInfo> data, bool* exc);
static Handle<JSObject> InstantiateObject(Handle<ObjectTemplateInfo> data,
bool* exc);
- static void ConfigureInstance(Handle<Object> instance,
+ static void ConfigureInstance(Isolate* isolate,
+ Handle<Object> instance,
Handle<Object> data,
bool* exc);
static Handle<String> GetStackTraceLine(Handle<Object> recv,
@@ -136,8 +145,8 @@
Handle<Object> pos,
Handle<Object> is_global);
#ifdef ENABLE_DEBUGGER_SUPPORT
- static Object* DebugBreakHelper();
- static void ProcessDebugMessages(bool debug_command_only);
+ static Object* DebugBreakHelper(Isolate* isolate);
+ static void ProcessDebugMessages(Isolate* isolate, bool debug_command_only);
#endif
// If the stack guard is triggered, but it is not an actual
@@ -147,14 +156,18 @@
// Get a function delegate (or undefined) for the given non-function
// object. Used for support calling objects as functions.
- static Handle<Object> GetFunctionDelegate(Handle<Object> object);
- static Handle<Object> TryGetFunctionDelegate(Handle<Object> object,
+ static Handle<Object> GetFunctionDelegate(Isolate* isolate,
+ Handle<Object> object);
+ static Handle<Object> TryGetFunctionDelegate(Isolate* isolate,
+ Handle<Object> object,
bool* has_pending_exception);
// Get a function delegate (or undefined) for the given non-function
// object. Used for support calling objects as constructors.
- static Handle<Object> GetConstructorDelegate(Handle<Object> object);
- static Handle<Object> TryGetConstructorDelegate(Handle<Object> object,
+ static Handle<Object> GetConstructorDelegate(Isolate* isolate,
+ Handle<Object> object);
+ static Handle<Object> TryGetConstructorDelegate(Isolate* isolate,
+ Handle<Object> object,
bool* has_pending_exception);
};
diff --git a/src/factory.cc b/src/factory.cc
index 2dddc9f..819e9f0 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -664,7 +664,7 @@
return result;
}
- if (V8::UseCrankshaft() &&
+ if (isolate()->use_crankshaft() &&
FLAG_always_opt &&
result->is_compiled() &&
!function_info->is_toplevel() &&
@@ -1586,7 +1586,8 @@
// instance template.
Handle<Object> instance_template(desc->instance_template(), isolate());
if (!instance_template->IsUndefined()) {
- Execution::ConfigureInstance(instance,
+ Execution::ConfigureInstance(isolate(),
+ instance,
instance_template,
pending_exception);
} else {
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 5c170ac..f19c4a6 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -240,7 +240,7 @@
DEFINE_bool(use_gvn, true, "use hydrogen global value numbering")
DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction canonicalizing")
DEFINE_bool(use_inlining, true, "use function inlining")
-DEFINE_bool(use_escape_analysis, false, "use hydrogen escape analysis")
+DEFINE_bool(use_escape_analysis, true, "use hydrogen escape analysis")
DEFINE_bool(use_allocation_folding, true, "use allocation folding")
DEFINE_int(max_inlining_levels, 5, "maximum number of inlining levels")
DEFINE_int(max_inlined_source_size, 600,
diff --git a/src/heap.cc b/src/heap.cc
index bd0a6f9..8487857 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -6716,6 +6716,12 @@
RoundUp(max_old_generation_size_,
Page::kPageSize));
+ // We rely on being able to allocate new arrays in paged spaces.
+ ASSERT(MaxRegularSpaceAllocationSize() >=
+ (JSArray::kSize +
+ FixedArray::SizeFor(JSObject::kInitialMaxFastElementArray) +
+ AllocationMemento::kSize));
+
configured_ = true;
return true;
}
diff --git a/src/heap.h b/src/heap.h
index 3bfd618..4071ef6 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -523,7 +523,7 @@
int InitialSemiSpaceSize() { return initial_semispace_size_; }
intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
intptr_t MaxExecutableSize() { return max_executable_size_; }
- int MaxRegularSpaceAllocationSize() { return InitialSemiSpaceSize() * 3/4; }
+ int MaxRegularSpaceAllocationSize() { return InitialSemiSpaceSize() * 4/5; }
// Returns the capacity of the heap in bytes w/o growing. Heap grows when
// more spaces are needed until it reaches the limit.
diff --git a/src/hydrogen-escape-analysis.cc b/src/hydrogen-escape-analysis.cc
index 0e70bcd..00cfe27 100644
--- a/src/hydrogen-escape-analysis.cc
+++ b/src/hydrogen-escape-analysis.cc
@@ -306,4 +306,13 @@
}
+void HEscapeAnalysisPhase::Run() {
+ // TODO(mstarzinger): We disable escape analysis with OSR for now, because
+ // spill slots might be uninitialized. Needs investigation.
+ if (graph()->has_osr()) return;
+ CollectCapturedValues();
+ PerformScalarReplacement();
+}
+
+
} } // namespace v8::internal
diff --git a/src/hydrogen-escape-analysis.h b/src/hydrogen-escape-analysis.h
index 639f5a9..311a653 100644
--- a/src/hydrogen-escape-analysis.h
+++ b/src/hydrogen-escape-analysis.h
@@ -45,10 +45,7 @@
cumulative_values_(0),
block_states_(graph->blocks()->length(), zone()) { }
- void Run() {
- CollectCapturedValues();
- PerformScalarReplacement();
- }
+ void Run();
private:
void CollectCapturedValues();
diff --git a/src/hydrogen-osr.cc b/src/hydrogen-osr.cc
index 73fa40a..bf6233b 100644
--- a/src/hydrogen-osr.cc
+++ b/src/hydrogen-osr.cc
@@ -117,8 +117,9 @@
const ZoneList<HPhi*>* phis = osr_loop_entry_->phis();
for (int j = 0; j < phis->length(); j++) {
HPhi* phi = phis->at(j);
- ASSERT(phi->HasMergedIndex());
- osr_values_->at(phi->merged_index())->set_incoming_value(phi);
+ if (phi->HasMergedIndex()) {
+ osr_values_->at(phi->merged_index())->set_incoming_value(phi);
+ }
}
}
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 0b1fe09..c42d035 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4003,13 +4003,18 @@
}
+static bool CanInlinePropertyAccess(Map* type) {
+ return !type->is_dictionary_map() && !type->has_named_interceptor();
+}
+
+
static void LookupInPrototypes(Handle<Map> map,
Handle<String> name,
LookupResult* lookup) {
while (map->prototype()->IsJSObject()) {
Handle<JSObject> holder(JSObject::cast(map->prototype()));
- if (!holder->HasFastProperties()) break;
map = Handle<Map>(holder->map());
+ if (!CanInlinePropertyAccess(*map)) break;
map->LookupDescriptor(*holder, *name, lookup);
if (lookup->IsFound()) return;
}
@@ -4397,8 +4402,8 @@
LookupResult* lookup,
bool is_store) {
ASSERT(!is_store || !type->is_observed());
- if (type->has_named_interceptor()) {
- lookup->InterceptorResult(NULL);
+ if (!CanInlinePropertyAccess(*type)) {
+ lookup->NotFound();
return false;
}
// If we directly find a field, the access can be inlined.
@@ -4541,8 +4546,7 @@
static bool CanLoadPropertyFromPrototype(Handle<Map> map,
Handle<Name> name,
LookupResult* lookup) {
- if (map->has_named_interceptor()) return false;
- if (map->is_dictionary_map()) return false;
+ if (!CanInlinePropertyAccess(*map)) return false;
map->LookupDescriptor(NULL, *name, lookup);
if (lookup->IsFound()) return false;
return true;
@@ -4634,9 +4638,8 @@
if (current->IsJSGlobalProxy() ||
current->IsGlobalObject() ||
!current->IsJSObject() ||
- JSObject::cast(current)->map()->has_named_interceptor() ||
- JSObject::cast(current)->IsAccessCheckNeeded() ||
- !JSObject::cast(current)->HasFastProperties()) {
+ !CanInlinePropertyAccess(JSObject::cast(current)->map()) ||
+ JSObject::cast(current)->IsAccessCheckNeeded()) {
return false;
}
@@ -4671,8 +4674,7 @@
LookupResult lookup(isolate());
if (ComputeLoadStoreField(map, name, &lookup, false) ||
(lookup.IsCacheable() &&
- !map->is_dictionary_map() &&
- !map->has_named_interceptor() &&
+ CanInlinePropertyAccess(*map) &&
(lookup.IsConstant() ||
(!lookup.IsFound() &&
PrototypeChainCanNeverResolve(map, name))))) {
@@ -4997,7 +4999,7 @@
Handle<Map> map;
if (monomorphic) {
map = types->first();
- if (map->is_dictionary_map()) monomorphic = false;
+ monomorphic = CanInlinePropertyAccess(*map);
}
if (monomorphic) {
Handle<JSFunction> setter;
@@ -5138,7 +5140,7 @@
map = types->first();
// We can't generate code for a monomorphic dict mode load so
// just pretend it is not monomorphic.
- if (map->is_dictionary_map()) monomorphic = false;
+ monomorphic = CanInlinePropertyAccess(*map);
}
if (monomorphic) {
Handle<JSFunction> getter;
@@ -5896,10 +5898,10 @@
bool monomorphic = false;
if (expr->IsMonomorphic()) {
map = types->first();
- monomorphic = !map->is_dictionary_map();
+ monomorphic = CanInlinePropertyAccess(*map);
} else if (object->HasMonomorphicJSObjectType()) {
map = object->GetMonomorphicJSObjectMap();
- monomorphic = !map->is_dictionary_map();
+ monomorphic = CanInlinePropertyAccess(*map);
}
if (monomorphic) {
Handle<JSFunction> getter;
@@ -7582,7 +7584,7 @@
SmallMapList* types = prop->GetReceiverTypes();
if (monomorphic) {
map = types->first();
- if (map->is_dictionary_map()) monomorphic = false;
+ monomorphic = CanInlinePropertyAccess(*map);
}
if (monomorphic) {
Handle<JSFunction> getter;
diff --git a/src/i18n.cc b/src/i18n.cc
index 40932b4..0ae19c8 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -872,7 +872,7 @@
v8::Utils::OpenPersistent(object))->GetInternalField(0));
// Then dispose of the persistent handle to JS object.
- object->Dispose(isolate);
+ object->Dispose();
}
@@ -936,7 +936,7 @@
v8::Utils::OpenPersistent(object))->GetInternalField(0));
// Then dispose of the persistent handle to JS object.
- object->Dispose(isolate);
+ object->Dispose();
}
@@ -997,7 +997,7 @@
v8::Utils::OpenPersistent(object))->GetInternalField(0));
// Then dispose of the persistent handle to JS object.
- object->Dispose(isolate);
+ object->Dispose();
}
@@ -1064,7 +1064,7 @@
v8::Utils::OpenPersistent(object))->GetInternalField(1));
// Then dispose of the persistent handle to JS object.
- object->Dispose(isolate);
+ object->Dispose();
}
} } // namespace v8::internal
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 6db381e..6a207ca 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -53,7 +53,7 @@
// Print the code after compiling it.
static void PrintCode(Handle<Code> code, CompilationInfo* info);
- static bool ShouldGenerateLog(Expression* type);
+ static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
static bool RecordPositions(MacroAssembler* masm,
int pos,
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 09966c9..db82b39 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -3266,7 +3266,7 @@
// 2 (array): Arguments to the format string.
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
+ if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
VisitForStackValue(args->at(1));
VisitForStackValue(args->at(2));
__ CallRuntime(Runtime::kLog, 2);
diff --git a/src/ic.cc b/src/ic.cc
index 2a1f83d..7f27d3f 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -500,7 +500,7 @@
Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) {
- Handle<Object> delegate = Execution::GetFunctionDelegate(object);
+ Handle<Object> delegate = Execution::GetFunctionDelegate(isolate(), object);
if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) {
// Patch the receiver and use the delegate as the function to
@@ -1719,7 +1719,8 @@
// Strict mode doesn't allow setting non-existent global property.
return ReferenceError("not_defined", name);
} else if (FLAG_use_ic &&
- (lookup.IsNormal() ||
+ (!name->IsCacheable(isolate()) ||
+ lookup.IsNormal() ||
(lookup.IsField() && lookup.CanHoldValue(value)))) {
Handle<Code> stub = strict_mode == kStrictMode
? generic_stub_strict() : generic_stub();
diff --git a/src/isolate.cc b/src/isolate.cc
index 0e7b6d5..39d75e2 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -226,8 +226,8 @@
PreallocatedMemoryThread()
: Thread("v8:PreallocMem"),
keep_running_(true),
- wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
- data_ready_semaphore_(OS::CreateSemaphore(0)),
+ wait_for_ever_semaphore_(new Semaphore(0)),
+ data_ready_semaphore_(new Semaphore(0)),
data_(NULL),
length_(0) {
}
@@ -1369,7 +1369,8 @@
// exception object to be set later must not be turned into a string.
if (exception_arg->IsJSObject() && !IsErrorObject(exception_arg)) {
bool failed = false;
- exception_arg = Execution::ToDetailString(exception_arg, &failed);
+ exception_arg =
+ Execution::ToDetailString(this, exception_arg, &failed);
if (failed) {
exception_arg = factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("exception"));
@@ -1792,6 +1793,8 @@
regexp_stack_(NULL),
date_cache_(NULL),
code_stub_interface_descriptors_(NULL),
+ has_fatal_error_(false),
+ use_crankshaft_(true),
initialized_from_snapshot_(false),
cpu_profiler_(NULL),
heap_profiler_(NULL),
@@ -2147,6 +2150,12 @@
stress_deopt_count_ = FLAG_deopt_every_n_times;
+ has_fatal_error_ = false;
+
+ use_crankshaft_ = FLAG_crankshaft
+ && !Serializer::enabled()
+ && CPU::SupportsCrankshaft();
+
if (function_entry_hook() != NULL) {
// When function entry hooking is in effect, we have to create the code
// stubs from scratch to get entry hooks, rather than loading the previously
@@ -2239,7 +2248,7 @@
InitializeThreadLocal();
bootstrapper_->Initialize(create_heap_objects);
- builtins_.SetUp(create_heap_objects);
+ builtins_.SetUp(this, create_heap_objects);
// Only preallocate on the first initialization.
if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) {
diff --git a/src/isolate.h b/src/isolate.h
index 8eace12..8be8af7 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1059,6 +1059,11 @@
thread_local_top_.top_lookup_result_ = top;
}
+ bool IsDead() { return has_fatal_error_; }
+ void SignalFatalError() { has_fatal_error_ = true; }
+
+ bool use_crankshaft() const { return use_crankshaft_; }
+
bool initialized_from_snapshot() { return initialized_from_snapshot_; }
double time_millis_since_init() {
@@ -1300,6 +1305,12 @@
unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
CodeStubInterfaceDescriptor* code_stub_interface_descriptors_;
+ // True if fatal error has been signaled for this isolate.
+ bool has_fatal_error_;
+
+ // True if we are using the Crankshaft optimizing compiler.
+ bool use_crankshaft_;
+
// True if this isolate was initialized from a snapshot.
bool initialized_from_snapshot_;
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 5ebdb40..2de1401 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -495,11 +495,13 @@
bool has_exception = false;
String* class_name = object->class_name();
if (class_name == isolate_->heap()->String_string()) {
- Handle<Object> value = Execution::ToString(object, &has_exception);
+ Handle<Object> value =
+ Execution::ToString(isolate_, object, &has_exception);
if (has_exception) return EXCEPTION;
SerializeString(Handle<String>::cast(value));
} else if (class_name == isolate_->heap()->Number_string()) {
- Handle<Object> value = Execution::ToNumber(object, &has_exception);
+ Handle<Object> value =
+ Execution::ToNumber(isolate_, object, &has_exception);
if (has_exception) return EXCEPTION;
if (value->IsSmi()) return SerializeSmi(Smi::cast(*value));
SerializeHeapNumber(Handle<HeapNumber>::cast(value));
diff --git a/src/log.cc b/src/log.cc
index 158d652..77bb9b3 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -556,7 +556,7 @@
} else {
buffer_[head_] = *sample;
head_ = Succ(head_);
- buffer_semaphore_->Signal(); // Tell we have an element.
+ buffer_semaphore_.Signal(); // Tell we have an element.
}
}
@@ -569,7 +569,7 @@
private:
// Waits for a signal and removes profiling data.
bool Remove(TickSample* sample) {
- buffer_semaphore_->Wait(); // Wait for an element.
+ buffer_semaphore_.Wait(); // Wait for an element.
*sample = buffer_[tail_];
bool result = overflow_;
tail_ = Succ(tail_);
@@ -589,7 +589,7 @@
int tail_; // Index to the buffer tail.
bool overflow_; // Tell whether a buffer overflow has occurred.
// Sempahore used for buffer synchronization.
- SmartPointer<Semaphore> buffer_semaphore_;
+ Semaphore buffer_semaphore_;
// Tells whether profiler is engaged, that is, processing thread is stated.
bool engaged_;
@@ -645,7 +645,7 @@
head_(0),
tail_(0),
overflow_(false),
- buffer_semaphore_(OS::CreateSemaphore(0)),
+ buffer_semaphore_(0),
engaged_(false),
running_(false),
paused_(false) {
diff --git a/src/marking-thread.cc b/src/marking-thread.cc
index ac9f944..58bca36 100644
--- a/src/marking-thread.cc
+++ b/src/marking-thread.cc
@@ -39,9 +39,9 @@
: Thread("MarkingThread"),
isolate_(isolate),
heap_(isolate->heap()),
- start_marking_semaphore_(OS::CreateSemaphore(0)),
- end_marking_semaphore_(OS::CreateSemaphore(0)),
- stop_semaphore_(OS::CreateSemaphore(0)) {
+ start_marking_semaphore_(0),
+ end_marking_semaphore_(0),
+ stop_semaphore_(0) {
NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(false));
id_ = NoBarrier_AtomicIncrement(&id_counter_, 1);
}
@@ -57,33 +57,33 @@
DisallowHandleDereference no_deref;
while (true) {
- start_marking_semaphore_->Wait();
+ start_marking_semaphore_.Wait();
if (Acquire_Load(&stop_thread_)) {
- stop_semaphore_->Signal();
+ stop_semaphore_.Signal();
return;
}
- end_marking_semaphore_->Signal();
+ end_marking_semaphore_.Signal();
}
}
void MarkingThread::Stop() {
Release_Store(&stop_thread_, static_cast<AtomicWord>(true));
- start_marking_semaphore_->Signal();
- stop_semaphore_->Wait();
+ start_marking_semaphore_.Signal();
+ stop_semaphore_.Wait();
Join();
}
void MarkingThread::StartMarking() {
- start_marking_semaphore_->Signal();
+ start_marking_semaphore_.Signal();
}
void MarkingThread::WaitForMarkingThread() {
- end_marking_semaphore_->Wait();
+ end_marking_semaphore_.Wait();
}
} } // namespace v8::internal
diff --git a/src/marking-thread.h b/src/marking-thread.h
index 9efa3af..021cd5b 100644
--- a/src/marking-thread.h
+++ b/src/marking-thread.h
@@ -43,24 +43,19 @@
class MarkingThread : public Thread {
public:
explicit MarkingThread(Isolate* isolate);
+ ~MarkingThread() {}
void Run();
void Stop();
void StartMarking();
void WaitForMarkingThread();
- ~MarkingThread() {
- delete start_marking_semaphore_;
- delete end_marking_semaphore_;
- delete stop_semaphore_;
- }
-
private:
Isolate* isolate_;
Heap* heap_;
- Semaphore* start_marking_semaphore_;
- Semaphore* end_marking_semaphore_;
- Semaphore* stop_semaphore_;
+ Semaphore start_marking_semaphore_;
+ Semaphore end_marking_semaphore_;
+ Semaphore stop_semaphore_;
volatile AtomicWord stop_thread_;
int id_;
static Atomic32 id_counter_;
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index 950df21..32d7d0d 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -63,7 +63,7 @@
// Print the code after compiling it.
static void PrintCode(Handle<Code> code, CompilationInfo* info);
- static bool ShouldGenerateLog(Expression* type);
+ static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
static void SetFunctionInfo(Handle<JSFunction> fun,
FunctionLiteral* lit,
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 37d6bcf..bf6f1c8 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -3331,7 +3331,7 @@
// 2 (array): Arguments to the format string.
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
+ if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
VisitForStackValue(args->at(1));
VisitForStackValue(args->at(2));
__ CallRuntime(Runtime::kLog, 2);
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index c1edcb1..9e63555 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -398,7 +398,7 @@
// context even after we have disposed of the context.
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags, "mksnapshot");
i::Object* raw_context = *v8::Utils::OpenPersistent(context);
- context.Dispose(isolate);
+ context.Dispose();
CppByteSink sink(argv[1]);
// This results in a somewhat smaller snapshot, probably because it gets rid
// of some things that are cached between garbage collections.
diff --git a/src/objects.cc b/src/objects.cc
index 2183fb4..80ca046 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1909,25 +1909,6 @@
}
-static bool IsIdentifier(UnicodeCache* cache, Name* name) {
- // Checks whether the buffer contains an identifier (no escape).
- if (!name->IsString()) return false;
- String* string = String::cast(name);
- if (string->length() == 0) return false;
- ConsStringIteratorOp op;
- StringCharacterStream stream(string, &op);
- if (!cache->IsIdentifierStart(stream.GetNext())) {
- return false;
- }
- while (stream.HasMore()) {
- if (!cache->IsIdentifierPart(stream.GetNext())) {
- return false;
- }
- }
- return true;
-}
-
-
MaybeObject* JSObject::AddFastProperty(Name* name,
Object* value,
PropertyAttributes attributes,
@@ -1943,10 +1924,7 @@
// hidden strings) and is not a real identifier.
// Normalize the object if it will have too many fast properties.
Isolate* isolate = GetHeap()->isolate();
- if ((!name->IsSymbol() &&
- !IsIdentifier(isolate->unicode_cache(), name) &&
- name != isolate->heap()->hidden_string()) ||
- TooManyFastProperties(store_mode)) {
+ if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) {
MaybeObject* maybe_failure =
NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
if (maybe_failure->IsFailure()) return maybe_failure;
@@ -7955,6 +7933,32 @@
#endif
+static bool IsIdentifier(UnicodeCache* cache, Name* name) {
+ // Checks whether the buffer contains an identifier (no escape).
+ if (!name->IsString()) return false;
+ String* string = String::cast(name);
+ if (string->length() == 0) return false;
+ ConsStringIteratorOp op;
+ StringCharacterStream stream(string, &op);
+ if (!cache->IsIdentifierStart(stream.GetNext())) {
+ return false;
+ }
+ while (stream.HasMore()) {
+ if (!cache->IsIdentifierPart(stream.GetNext())) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+bool Name::IsCacheable(Isolate* isolate) {
+ return IsSymbol() ||
+ IsIdentifier(isolate->unicode_cache(), this) ||
+ this == isolate->heap()->hidden_string();
+}
+
+
bool String::LooksValid() {
if (!Isolate::Current()->heap()->Contains(this)) return false;
return true;
@@ -12123,7 +12127,8 @@
if (object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
bool has_exception;
- Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ Handle<Object> number =
+ Execution::ToNumber(object->GetIsolate(), value, &has_exception);
if (has_exception) return Handle<Object>();
value = number;
}
diff --git a/src/objects.h b/src/objects.h
index bf0d240..e4017ef 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2680,10 +2680,9 @@
// don't want to be wasteful with long lived objects.
static const int kMaxUncheckedOldFastElementsLength = 500;
- // TODO(2790): HAllocate currently always allocates fast backing stores
- // in new space, where on x64 we can only fit ~98K elements. Keep this
- // limit lower than that until HAllocate is made smarter.
- static const int kInitialMaxFastElementArray = 95000;
+ // Note that Heap::MaxRegularSpaceAllocationSize() puts a limit on
+ // permissible values (see the ASSERT in heap.cc).
+ static const int kInitialMaxFastElementArray = 100000;
static const int kFastPropertiesSoftLimit = 12;
static const int kMaxFastProperties = 64;
@@ -7995,6 +7994,8 @@
// Casting.
static inline Name* cast(Object* obj);
+ bool IsCacheable(Isolate* isolate);
+
DECLARE_PRINTER(Name)
// Layout description.
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index 1f77d5a..96847dc 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -52,7 +52,7 @@
if (FLAG_trace_concurrent_recompilation) total_timer.Start();
while (true) {
- input_queue_semaphore_->Wait();
+ input_queue_semaphore_.Wait();
Logger::TimerEventScope timer(
isolate_, Logger::TimerEventScope::v8_recompile_concurrent);
@@ -67,7 +67,7 @@
if (FLAG_trace_concurrent_recompilation) {
time_spent_total_ = total_timer.Elapsed();
}
- stop_semaphore_->Signal();
+ stop_semaphore_.Signal();
return;
case FLUSH:
// The main thread is blocked, waiting for the stop semaphore.
@@ -76,7 +76,7 @@
}
Release_Store(&queue_length_, static_cast<AtomicWord>(0));
Release_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE));
- stop_semaphore_->Signal();
+ stop_semaphore_.Signal();
// Return to start of consumer loop.
continue;
}
@@ -123,7 +123,7 @@
while (input_queue_.Dequeue(&optimizing_compiler)) {
// This should not block, since we have one signal on the input queue
// semaphore corresponding to each element in the input queue.
- input_queue_semaphore_->Wait();
+ input_queue_semaphore_.Wait();
CompilationInfo* info = optimizing_compiler->info();
if (restore_function_code) {
Handle<JSFunction> function = info->closure();
@@ -151,8 +151,8 @@
void OptimizingCompilerThread::Flush() {
ASSERT(!IsOptimizerThread());
Release_Store(&stop_thread_, static_cast<AtomicWord>(FLUSH));
- input_queue_semaphore_->Signal();
- stop_semaphore_->Wait();
+ input_queue_semaphore_.Signal();
+ stop_semaphore_.Wait();
FlushOutputQueue(true);
}
@@ -160,8 +160,8 @@
void OptimizingCompilerThread::Stop() {
ASSERT(!IsOptimizerThread());
Release_Store(&stop_thread_, static_cast<AtomicWord>(STOP));
- input_queue_semaphore_->Signal();
- stop_semaphore_->Wait();
+ input_queue_semaphore_.Signal();
+ stop_semaphore_.Wait();
if (FLAG_concurrent_recompilation_delay != 0) {
// Barrier when loading queue length is not necessary since the write
@@ -204,7 +204,7 @@
Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(1));
optimizing_compiler->info()->closure()->MarkInRecompileQueue();
input_queue_.Enqueue(optimizing_compiler);
- input_queue_semaphore_->Signal();
+ input_queue_semaphore_.Signal();
}
diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h
index 10ed420..bb96c74 100644
--- a/src/optimizing-compiler-thread.h
+++ b/src/optimizing-compiler-thread.h
@@ -50,11 +50,12 @@
thread_id_(0),
#endif
isolate_(isolate),
- stop_semaphore_(OS::CreateSemaphore(0)),
- input_queue_semaphore_(OS::CreateSemaphore(0)) {
+ stop_semaphore_(0),
+ input_queue_semaphore_(0) {
NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE));
NoBarrier_Store(&queue_length_, static_cast<AtomicWord>(0));
}
+ ~OptimizingCompilerThread() {}
void Run();
void Stop();
@@ -80,13 +81,6 @@
bool IsOptimizerThread();
#endif
- ~OptimizingCompilerThread() {
- delete input_queue_semaphore_;
- delete stop_semaphore_;
-#ifdef DEBUG
-#endif
- }
-
private:
enum StopFlag { CONTINUE, STOP, FLUSH };
@@ -101,8 +95,8 @@
#endif
Isolate* isolate_;
- Semaphore* stop_semaphore_;
- Semaphore* input_queue_semaphore_;
+ Semaphore stop_semaphore_;
+ Semaphore input_queue_semaphore_;
UnboundQueue<OptimizingCompiler*> input_queue_;
UnboundQueue<OptimizingCompiler*> output_queue_;
Mutex install_mutex_;
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index 7bedfe8..10525d9 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -398,71 +398,6 @@
}
-class CygwinSemaphore : public Semaphore {
- public:
- explicit CygwinSemaphore(int count) { sem_init(&sem_, 0, count); }
- virtual ~CygwinSemaphore() { sem_destroy(&sem_); }
-
- virtual void Wait();
- virtual bool Wait(int timeout);
- virtual void Signal() { sem_post(&sem_); }
- private:
- sem_t sem_;
-};
-
-
-void CygwinSemaphore::Wait() {
- while (true) {
- int result = sem_wait(&sem_);
- if (result == 0) return; // Successfully got semaphore.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-#ifndef TIMEVAL_TO_TIMESPEC
-#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-} while (false)
-#endif
-
-
-bool CygwinSemaphore::Wait(int timeout) {
- const long kOneSecondMicros = 1000000; // NOLINT
-
- // Split timeout into second and nanosecond parts.
- struct timeval delta;
- delta.tv_usec = timeout % kOneSecondMicros;
- delta.tv_sec = timeout / kOneSecondMicros;
-
- struct timeval current_time;
- // Get the current time.
- if (gettimeofday(¤t_time, NULL) == -1) {
- return false;
- }
-
- // Calculate time for end of timeout.
- struct timeval end_time;
- timeradd(¤t_time, &delta, &end_time);
-
- struct timespec ts;
- TIMEVAL_TO_TIMESPEC(&end_time, &ts);
- // Wait for semaphore signalled or timeout.
- while (true) {
- int result = sem_timedwait(&sem_, &ts);
- if (result == 0) return true; // Successfully got semaphore.
- if (result == -1 && errno == ETIMEDOUT) return false; // Timeout.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new CygwinSemaphore(count);
-}
-
-
void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 0b32b32..5e4e828 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -372,62 +372,6 @@
}
-class FreeBSDSemaphore : public Semaphore {
- public:
- explicit FreeBSDSemaphore(int count) { sem_init(&sem_, 0, count); }
- virtual ~FreeBSDSemaphore() { sem_destroy(&sem_); }
-
- virtual void Wait();
- virtual bool Wait(int timeout);
- virtual void Signal() { sem_post(&sem_); }
- private:
- sem_t sem_;
-};
-
-
-void FreeBSDSemaphore::Wait() {
- while (true) {
- int result = sem_wait(&sem_);
- if (result == 0) return; // Successfully got semaphore.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-bool FreeBSDSemaphore::Wait(int timeout) {
- const long kOneSecondMicros = 1000000; // NOLINT
-
- // Split timeout into second and nanosecond parts.
- struct timeval delta;
- delta.tv_usec = timeout % kOneSecondMicros;
- delta.tv_sec = timeout / kOneSecondMicros;
-
- struct timeval current_time;
- // Get the current time.
- if (gettimeofday(¤t_time, NULL) == -1) {
- return false;
- }
-
- // Calculate time for end of timeout.
- struct timeval end_time;
- timeradd(¤t_time, &delta, &end_time);
-
- struct timespec ts;
- TIMEVAL_TO_TIMESPEC(&end_time, &ts);
- while (true) {
- int result = sem_timedwait(&sem_, &ts);
- if (result == 0) return true; // Successfully got semaphore.
- if (result == -1 && errno == ETIMEDOUT) return false; // Timeout.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new FreeBSDSemaphore(count);
-}
-
-
void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 37b4b11..3416da3 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -497,76 +497,6 @@
}
-class LinuxSemaphore : public Semaphore {
- public:
- explicit LinuxSemaphore(int count) { sem_init(&sem_, 0, count); }
- virtual ~LinuxSemaphore() { sem_destroy(&sem_); }
-
- virtual void Wait();
- virtual bool Wait(int timeout);
- virtual void Signal() { sem_post(&sem_); }
- private:
- sem_t sem_;
-};
-
-
-void LinuxSemaphore::Wait() {
- while (true) {
- int result = sem_wait(&sem_);
- if (result == 0) return; // Successfully got semaphore.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-#ifndef TIMEVAL_TO_TIMESPEC
-#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-} while (false)
-#endif
-
-
-bool LinuxSemaphore::Wait(int timeout) {
- const long kOneSecondMicros = 1000000; // NOLINT
-
- // Split timeout into second and nanosecond parts.
- struct timeval delta;
- delta.tv_usec = timeout % kOneSecondMicros;
- delta.tv_sec = timeout / kOneSecondMicros;
-
- struct timeval current_time;
- // Get the current time.
- if (gettimeofday(¤t_time, NULL) == -1) {
- return false;
- }
-
- // Calculate time for end of timeout.
- struct timeval end_time;
- timeradd(¤t_time, &delta, &end_time);
-
- struct timespec ts;
- TIMEVAL_TO_TIMESPEC(&end_time, &ts);
- // Wait for semaphore signalled or timeout.
- while (true) {
- int result = sem_timedwait(&sem_, &ts);
- if (result == 0) return true; // Successfully got semaphore.
- if (result > 0) {
- // For glibc prior to 2.3.4 sem_timedwait returns the error instead of -1.
- errno = result;
- result = -1;
- }
- if (result == -1 && errno == ETIMEDOUT) return false; // Timeout.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new LinuxSemaphore(count);
-}
-
-
void OS::SetUp() {
// Seed the random number generator. We preserve microsecond resolution.
uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()) ^ (getpid() << 16);
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 7aa02a7..d6d3128 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -392,53 +392,6 @@
}
-class MacOSSemaphore : public Semaphore {
- public:
- explicit MacOSSemaphore(int count) {
- int r;
- r = semaphore_create(mach_task_self(),
- &semaphore_,
- SYNC_POLICY_FIFO,
- count);
- ASSERT(r == KERN_SUCCESS);
- }
-
- ~MacOSSemaphore() {
- int r;
- r = semaphore_destroy(mach_task_self(), semaphore_);
- ASSERT(r == KERN_SUCCESS);
- }
-
- void Wait() {
- int r;
- do {
- r = semaphore_wait(semaphore_);
- ASSERT(r == KERN_SUCCESS || r == KERN_ABORTED);
- } while (r == KERN_ABORTED);
- }
-
- bool Wait(int timeout);
-
- void Signal() { semaphore_signal(semaphore_); }
-
- private:
- semaphore_t semaphore_;
-};
-
-
-bool MacOSSemaphore::Wait(int timeout) {
- mach_timespec_t ts;
- ts.tv_sec = timeout / 1000000;
- ts.tv_nsec = (timeout % 1000000) * 1000;
- return semaphore_timedwait(semaphore_, ts) != KERN_OPERATION_TIMED_OUT;
-}
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new MacOSSemaphore(count);
-}
-
-
void OS::SetUp() {
// Seed the random number generator. We preserve microsecond resolution.
uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()) ^ (getpid() << 16);
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index 114b8e2..84039d3 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -429,75 +429,6 @@
}
-class OpenBSDSemaphore : public Semaphore {
- public:
- explicit OpenBSDSemaphore(int count) { sem_init(&sem_, 0, count); }
- virtual ~OpenBSDSemaphore() { sem_destroy(&sem_); }
-
- virtual void Wait();
- virtual bool Wait(int timeout);
- virtual void Signal() { sem_post(&sem_); }
- private:
- sem_t sem_;
-};
-
-
-void OpenBSDSemaphore::Wait() {
- while (true) {
- int result = sem_wait(&sem_);
- if (result == 0) return; // Successfully got semaphore.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-#ifndef TIMEVAL_TO_TIMESPEC
-#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-} while (false)
-#endif
-
-
-bool OpenBSDSemaphore::Wait(int timeout) {
- const long kOneSecondMicros = 1000000; // NOLINT
-
- // Split timeout into second and nanosecond parts.
- struct timeval delta;
- delta.tv_usec = timeout % kOneSecondMicros;
- delta.tv_sec = timeout / kOneSecondMicros;
-
- struct timeval current_time;
- // Get the current time.
- if (gettimeofday(¤t_time, NULL) == -1) {
- return false;
- }
-
- // Calculate time for end of timeout.
- struct timeval end_time;
- timeradd(¤t_time, &delta, &end_time);
-
- struct timespec ts;
- TIMEVAL_TO_TIMESPEC(&end_time, &ts);
-
- int to = ts.tv_sec;
-
- while (true) {
- int result = sem_trywait(&sem_);
- if (result == 0) return true; // Successfully got semaphore.
- if (!to) return false; // Timeout.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- usleep(ts.tv_nsec / 1000);
- to--;
- }
-}
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new OpenBSDSemaphore(count);
-}
-
-
void OS::SetUp() {
// Seed the random number generator. We preserve microsecond resolution.
uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()) ^ (getpid() << 16);
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index dd5c7a0..99636d6 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -393,84 +393,6 @@
}
-class SolarisSemaphore : public Semaphore {
- public:
- explicit SolarisSemaphore(int count) { sem_init(&sem_, 0, count); }
- virtual ~SolarisSemaphore() { sem_destroy(&sem_); }
-
- virtual void Wait();
- virtual bool Wait(int timeout);
- virtual void Signal() { sem_post(&sem_); }
- private:
- sem_t sem_;
-};
-
-
-void SolarisSemaphore::Wait() {
- while (true) {
- int result = sem_wait(&sem_);
- if (result == 0) return; // Successfully got semaphore.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-#ifndef TIMEVAL_TO_TIMESPEC
-#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
-} while (false)
-#endif
-
-
-#ifndef timeradd
-#define timeradd(a, b, result) \
- do { \
- (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
- (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
- if ((result)->tv_usec >= 1000000) { \
- ++(result)->tv_sec; \
- (result)->tv_usec -= 1000000; \
- } \
- } while (0)
-#endif
-
-
-bool SolarisSemaphore::Wait(int timeout) {
- const long kOneSecondMicros = 1000000; // NOLINT
-
- // Split timeout into second and nanosecond parts.
- struct timeval delta;
- delta.tv_usec = timeout % kOneSecondMicros;
- delta.tv_sec = timeout / kOneSecondMicros;
-
- struct timeval current_time;
- // Get the current time.
- if (gettimeofday(¤t_time, NULL) == -1) {
- return false;
- }
-
- // Calculate time for end of timeout.
- struct timeval end_time;
- timeradd(¤t_time, &delta, &end_time);
-
- struct timespec ts;
- TIMEVAL_TO_TIMESPEC(&end_time, &ts);
- // Wait for semaphore signalled or timeout.
- while (true) {
- int result = sem_timedwait(&sem_, &ts);
- if (result == 0) return true; // Successfully got semaphore.
- if (result == -1 && errno == ETIMEDOUT) return false; // Timeout.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
-}
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new SolarisSemaphore(count);
-}
-
-
void OS::SetUp() {
// Seed the random number generator.
// Convert the current time to a 64-bit integer first, before converting it
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 2775453..199ed2d 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1616,49 +1616,6 @@
// ----------------------------------------------------------------------------
-// Win32 semaphore support.
-//
-// On Win32 semaphores are implemented using Win32 Semaphore objects. The
-// semaphores are anonymous. Also, the semaphores are initialized to have
-// no upper limit on count.
-
-
-class Win32Semaphore : public Semaphore {
- public:
- explicit Win32Semaphore(int count) {
- sem = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL);
- }
-
- ~Win32Semaphore() {
- CloseHandle(sem);
- }
-
- void Wait() {
- WaitForSingleObject(sem, INFINITE);
- }
-
- bool Wait(int timeout) {
- // Timeout in Windows API is in milliseconds.
- DWORD millis_timeout = timeout / 1000;
- return WaitForSingleObject(sem, millis_timeout) != WAIT_TIMEOUT;
- }
-
- void Signal() {
- LONG dummy;
- ReleaseSemaphore(sem, 1, &dummy);
- }
-
- private:
- HANDLE sem;
-};
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- return new Win32Semaphore(count);
-}
-
-
-// ----------------------------------------------------------------------------
// Win32 socket support.
//
diff --git a/src/platform.h b/src/platform.h
index 5f93106..8565775 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -47,6 +47,7 @@
#include <cstdarg>
#include "platform/mutex.h"
+#include "platform/semaphore.h"
#include "utils.h"
#include "v8globals.h"
@@ -93,8 +94,6 @@
namespace v8 {
namespace internal {
-class Semaphore;
-
double ceiling(double x);
double modulo(double x, double y);
@@ -288,10 +287,6 @@
static int StackWalk(Vector<StackFrame> frames);
- // Factory method for creating platform dependent Semaphore.
- // Please use delete to reclaim the storage for the returned Semaphore.
- static Semaphore* CreateSemaphore(int count);
-
// Factory method for creating platform dependent Socket.
// Please use delete to reclaim the storage for the returned Socket.
static Socket* CreateSocket();
@@ -510,59 +505,6 @@
// ----------------------------------------------------------------------------
-// Semaphore
-//
-// A semaphore object is a synchronization object that maintains a count. The
-// count is decremented each time a thread completes a wait for the semaphore
-// object and incremented each time a thread signals the semaphore. When the
-// count reaches zero, threads waiting for the semaphore blocks until the
-// count becomes non-zero.
-
-class Semaphore {
- public:
- virtual ~Semaphore() {}
-
- // Suspends the calling thread until the semaphore counter is non zero
- // and then decrements the semaphore counter.
- virtual void Wait() = 0;
-
- // Suspends the calling thread until the counter is non zero or the timeout
- // time has passed. If timeout happens the return value is false and the
- // counter is unchanged. Otherwise the semaphore counter is decremented and
- // true is returned. The timeout value is specified in microseconds.
- virtual bool Wait(int timeout) = 0;
-
- // Increments the semaphore counter.
- virtual void Signal() = 0;
-};
-
-template <int InitialValue>
-struct CreateSemaphoreTrait {
- static Semaphore* Create() {
- return OS::CreateSemaphore(InitialValue);
- }
-};
-
-// POD Semaphore initialized lazily (i.e. the first time Pointer() is called).
-// Usage:
-// // The following semaphore starts at 0.
-// static LazySemaphore<0>::type my_semaphore = LAZY_SEMAPHORE_INITIALIZER;
-//
-// void my_function() {
-// // Do something with my_semaphore.Pointer().
-// }
-//
-template <int InitialValue>
-struct LazySemaphore {
- typedef typename LazyDynamicInstance<
- Semaphore, CreateSemaphoreTrait<InitialValue>,
- ThreadSafeInitOnceTrait>::type type;
-};
-
-#define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER
-
-
-// ----------------------------------------------------------------------------
// Thread
//
// Thread objects are used for creating and running threads. When the start()
@@ -604,7 +546,7 @@
// Start new thread and wait until Run() method is called on the new thread.
void StartSynchronously() {
- start_semaphore_ = OS::CreateSemaphore(0);
+ start_semaphore_ = new Semaphore(0);
Start();
start_semaphore_->Wait();
delete start_semaphore_;
diff --git a/src/platform/condition-variable.cc b/src/platform/condition-variable.cc
new file mode 100644
index 0000000..84df976
--- /dev/null
+++ b/src/platform/condition-variable.cc
@@ -0,0 +1,345 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "platform/condition-variable.h"
+
+#include <cerrno>
+#include <ctime>
+
+#include "platform/time.h"
+
+namespace v8 {
+namespace internal {
+
+#if V8_OS_POSIX
+
+ConditionVariable::ConditionVariable() {
+ // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary
+ // hack to support cross-compiling Chrome for Android in AOSP. Remove
+ // this once AOSP is fixed.
+#if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || V8_LIBC_GLIBC) && \
+ !V8_LIBRT_NOT_AVAILABLE
+ // On Free/Net/OpenBSD and Linux with glibc we can change the time
+ // source for pthread_cond_timedwait() to use the monotonic clock.
+ pthread_condattr_t attr;
+ int result = pthread_condattr_init(&attr);
+ ASSERT_EQ(0, result);
+ result = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ ASSERT_EQ(0, result);
+ result = pthread_cond_init(&native_handle_, &attr);
+ ASSERT_EQ(0, result);
+ result = pthread_condattr_destroy(&attr);
+#else
+ int result = pthread_cond_init(&native_handle_, NULL);
+#endif
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+ConditionVariable::~ConditionVariable() {
+ int result = pthread_cond_destroy(&native_handle_);
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+void ConditionVariable::NotifyOne() {
+ int result = pthread_cond_signal(&native_handle_);
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+void ConditionVariable::NotifyAll() {
+ int result = pthread_cond_broadcast(&native_handle_);
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+void ConditionVariable::Wait(Mutex* mutex) {
+ mutex->AssertHeldAndUnmark();
+ int result = pthread_cond_wait(&native_handle_, &mutex->native_handle());
+ ASSERT_EQ(0, result);
+ USE(result);
+ mutex->AssertUnheldAndMark();
+}
+
+
+bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
+ struct timespec ts;
+ int result;
+ mutex->AssertHeldAndUnmark();
+#if V8_OS_MACOSX
+ // Mac OS X provides pthread_cond_timedwait_relative_np(), which does
+ // not depend on the real time clock, which is what you really WANT here!
+ ts = rel_time.ToTimespec();
+ ASSERT_GE(ts.tv_sec, 0);
+ ASSERT_GE(ts.tv_nsec, 0);
+ result = pthread_cond_timedwait_relative_np(
+ &native_handle_, &mutex->native_handle(), &ts);
+#else
+ // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary
+ // hack to support cross-compiling Chrome for Android in AOSP. Remove
+ // this once AOSP is fixed.
+#if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || V8_LIBC_GLIBC) && \
+ !V8_LIBRT_NOT_AVAILABLE
+ // On Free/Net/OpenBSD and Linux with glibc we can change the time
+ // source for pthread_cond_timedwait() to use the monotonic clock.
+ result = clock_gettime(CLOCK_MONOTONIC, &ts);
+ ASSERT_EQ(0, result);
+ Time now = Time::FromTimespec(ts);
+#else
+ // The timeout argument to pthread_cond_timedwait() is in absolute time.
+ Time now = Time::NowFromSystemTime();
+#endif
+ Time end_time = now + rel_time;
+ ASSERT_GE(end_time, now);
+ ts = end_time.ToTimespec();
+ result = pthread_cond_timedwait(
+ &native_handle_, &mutex->native_handle(), &ts);
+#endif // V8_OS_MACOSX
+ mutex->AssertUnheldAndMark();
+ if (result == ETIMEDOUT) {
+ return false;
+ }
+ ASSERT_EQ(0, result);
+ return true;
+}
+
+#elif V8_OS_WIN
+
+struct ConditionVariable::Event {
+ Event() : handle_(::CreateEventA(NULL, true, false, NULL)) {
+ ASSERT(handle_ != NULL);
+ }
+
+ ~Event() {
+ BOOL ok = ::CloseHandle(handle_);
+ ASSERT(ok);
+ USE(ok);
+ }
+
+ bool WaitFor(DWORD timeout_ms) {
+ DWORD result = ::WaitForSingleObject(handle_, timeout_ms);
+ if (result == WAIT_OBJECT_0) {
+ return true;
+ }
+ ASSERT(result == WAIT_TIMEOUT);
+ return false;
+ }
+
+ HANDLE handle_;
+ Event* next_;
+ HANDLE thread_;
+ volatile bool notified_;
+};
+
+
+ConditionVariable::NativeHandle::~NativeHandle() {
+ ASSERT(waitlist_ == NULL);
+
+ while (freelist_ != NULL) {
+ Event* event = freelist_;
+ freelist_ = event->next_;
+ delete event;
+ }
+}
+
+
+ConditionVariable::Event* ConditionVariable::NativeHandle::Pre() {
+ LockGuard<Mutex> lock_guard(&mutex_);
+
+ // Grab an event from the free list or create a new one.
+ Event* event = freelist_;
+ if (event != NULL) {
+ freelist_ = event->next_;
+ } else {
+ event = new Event;
+ }
+ event->thread_ = GetCurrentThread();
+ event->notified_ = false;
+
+#ifdef DEBUG
+ // The event must not be on the wait list.
+ for (Event* we = waitlist_; we != NULL; we = we->next_) {
+ ASSERT_NE(event, we);
+ }
+#endif
+
+ // Prepend the event to the wait list.
+ event->next_ = waitlist_;
+ waitlist_ = event;
+
+ return event;
+}
+
+
+void ConditionVariable::NativeHandle::Post(Event* event, bool result) {
+ LockGuard<Mutex> lock_guard(&mutex_);
+
+ // Remove the event from the wait list.
+ for (Event** wep = &waitlist_;; wep = &(*wep)->next_) {
+ ASSERT_NE(NULL, *wep);
+ if (*wep == event) {
+ *wep = event->next_;
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ // The event must not be on the free list.
+ for (Event* fe = freelist_; fe != NULL; fe = fe->next_) {
+ ASSERT_NE(event, fe);
+ }
+#endif
+
+ // Reset the event.
+ BOOL ok = ::ResetEvent(event->handle_);
+ ASSERT(ok);
+ USE(ok);
+
+ // Insert the event into the free list.
+ event->next_ = freelist_;
+ freelist_ = event;
+
+ // Forward signals delivered after the timeout to the next waiting event.
+ if (!result && event->notified_ && waitlist_ != NULL) {
+ ok = ::SetEvent(waitlist_->handle_);
+ ASSERT(ok);
+ USE(ok);
+ waitlist_->notified_ = true;
+ }
+}
+
+
+ConditionVariable::ConditionVariable() {}
+
+
+ConditionVariable::~ConditionVariable() {}
+
+
+void ConditionVariable::NotifyOne() {
+ // Notify the thread with the highest priority in the waitlist
+ // that was not already signalled.
+ LockGuard<Mutex> lock_guard(native_handle_.mutex());
+ Event* highest_event = NULL;
+ int highest_priority = std::numeric_limits<int>::min();
+ for (Event* event = native_handle().waitlist();
+ event != NULL;
+ event = event->next_) {
+ if (event->notified_) {
+ continue;
+ }
+ int priority = GetThreadPriority(event->thread_);
+ ASSERT_NE(THREAD_PRIORITY_ERROR_RETURN, priority);
+ if (priority >= highest_priority) {
+ highest_priority = priority;
+ highest_event = event;
+ }
+ }
+ if (highest_event != NULL) {
+ ASSERT(!highest_event->notified_);
+ ::SetEvent(highest_event->handle_);
+ highest_event->notified_ = true;
+ }
+}
+
+
+void ConditionVariable::NotifyAll() {
+ // Notify all threads on the waitlist.
+ LockGuard<Mutex> lock_guard(native_handle_.mutex());
+ for (Event* event = native_handle().waitlist();
+ event != NULL;
+ event = event->next_) {
+ if (!event->notified_) {
+ ::SetEvent(event->handle_);
+ event->notified_ = true;
+ }
+ }
+}
+
+
+void ConditionVariable::Wait(Mutex* mutex) {
+ // Create and setup the wait event.
+ Event* event = native_handle_.Pre();
+
+ // Release the user mutex.
+ mutex->Unlock();
+
+ // Wait on the wait event.
+ while (!event->WaitFor(INFINITE))
+ ;
+
+ // Reaquire the user mutex.
+ mutex->Lock();
+
+ // Release the wait event (we must have been notified).
+ ASSERT(event->notified_);
+ native_handle_.Post(event, true);
+}
+
+
+bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
+ // Create and setup the wait event.
+ Event* event = native_handle_.Pre();
+
+ // Release the user mutex.
+ mutex->Unlock();
+
+ // Wait on the wait event.
+ TimeTicks now = TimeTicks::Now();
+ TimeTicks end = now + rel_time;
+ bool result = false;
+ while (true) {
+ int64_t msec = (end - now).InMilliseconds();
+ if (msec >= static_cast<int64_t>(INFINITE)) {
+ result = event->WaitFor(INFINITE - 1);
+ if (result) {
+ break;
+ }
+ now = TimeTicks::Now();
+ } else {
+ result = event->WaitFor((msec < 0) ? 0 : static_cast<DWORD>(msec));
+ break;
+ }
+ }
+
+ // Reaquire the user mutex.
+ mutex->Lock();
+
+ // Release the wait event.
+ ASSERT(!result || event->notified_);
+ native_handle_.Post(event, result);
+
+ return result;
+}
+
+#endif // V8_OS_POSIX
+
+} } // namespace v8::internal
diff --git a/src/platform/condition-variable.h b/src/platform/condition-variable.h
new file mode 100644
index 0000000..43cc529
--- /dev/null
+++ b/src/platform/condition-variable.h
@@ -0,0 +1,140 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_CONDITION_VARIABLE_H_
+#define V8_PLATFORM_CONDITION_VARIABLE_H_
+
+#include "platform/mutex.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class ConditionVariableEvent;
+class TimeDelta;
+
+// -----------------------------------------------------------------------------
+// ConditionVariable
+//
+// This class is a synchronization primitive that can be used to block a thread,
+// or multiple threads at the same time, until:
+// - a notification is received from another thread,
+// - a timeout expires, or
+// - a spurious wakeup occurs
+// Any thread that intends to wait on a ConditionVariable has to acquire a lock
+// on a Mutex first. The |Wait()| and |WaitFor()| operations atomically release
+// the mutex and suspend the execution of the calling thread. When the condition
+// variable is notified, the thread is awakened, and the mutex is reacquired.
+
+class ConditionVariable V8_FINAL {
+ public:
+ ConditionVariable();
+ ~ConditionVariable();
+
+ // If any threads are waiting on this condition variable, calling
+ // |NotifyOne()| unblocks one of the waiting threads.
+ void NotifyOne();
+
+ // Unblocks all threads currently waiting for this condition variable.
+ void NotifyAll();
+
+ // |Wait()| causes the calling thread to block until the condition variable is
+ // notified or a spurious wakeup occurs. Atomically releases the mutex, blocks
+ // the current executing thread, and adds it to the list of threads waiting on
+ // this condition variable. The thread will be unblocked when |NotifyAll()| or
+ // |NotifyOne()| is executed. It may also be unblocked spuriously. When
+ // unblocked, regardless of the reason, the lock on the mutex is reacquired
+ // and |Wait()| exits.
+ void Wait(Mutex* mutex);
+
+ // Atomically releases the mutex, blocks the current executing thread, and
+ // adds it to the list of threads waiting on this condition variable. The
+ // thread will be unblocked when |NotifyAll()| or |NotifyOne()| is executed,
+ // or when the relative timeout |rel_time| expires. It may also be unblocked
+ // spuriously. When unblocked, regardless of the reason, the lock on the mutex
+ // is reacquired and |WaitFor()| exits. Returns true if the condition variable
+ // was notified prior to the timeout.
+ bool WaitFor(Mutex* mutex, const TimeDelta& rel_time) V8_WARN_UNUSED_RESULT;
+
+ // The implementation-defined native handle type.
+#if V8_OS_POSIX
+ typedef pthread_cond_t NativeHandle;
+#elif V8_OS_WIN
+ struct Event;
+ class NativeHandle V8_FINAL {
+ public:
+ NativeHandle() : waitlist_(NULL), freelist_(NULL) {}
+ ~NativeHandle();
+
+ Event* Pre() V8_WARN_UNUSED_RESULT;
+ void Post(Event* event, bool result);
+
+ Mutex* mutex() { return &mutex_; }
+ Event* waitlist() { return waitlist_; }
+
+ private:
+ Event* waitlist_;
+ Event* freelist_;
+ Mutex mutex_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeHandle);
+ };
+#endif
+
+ NativeHandle& native_handle() V8_WARN_UNUSED_RESULT {
+ return native_handle_;
+ }
+ const NativeHandle& native_handle() const V8_WARN_UNUSED_RESULT {
+ return native_handle_;
+ }
+
+ private:
+ NativeHandle native_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
+};
+
+
+// POD ConditionVariable initialized lazily (i.e. the first time Pointer() is
+// called).
+// Usage:
+// static LazyConditionVariable my_condvar =
+// LAZY_CONDITION_VARIABLE_INITIALIZER;
+//
+// void my_function() {
+// LockGuard<Mutex> lock_guard(&my_mutex);
+// my_condvar.Pointer()->Wait(&my_mutex);
+// }
+typedef LazyStaticInstance<ConditionVariable,
+ DefaultConstructTrait<ConditionVariable>,
+ ThreadSafeInitOnceTrait>::type LazyConditionVariable;
+
+#define LAZY_CONDITION_VARIABLE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
+
+} } // namespace v8::internal
+
+#endif // V8_PLATFORM_CONDITION_VARIABLE_H_
diff --git a/src/platform/mutex.cc b/src/platform/mutex.cc
index c8d75c7..1a7c69a 100644
--- a/src/platform/mutex.cc
+++ b/src/platform/mutex.cc
@@ -101,32 +101,32 @@
#elif V8_OS_WIN
-static V8_INLINE(void InitializeNativeHandle(CRITICAL_SECTION* cs)) {
+static V8_INLINE(void InitializeNativeHandle(PCRITICAL_SECTION cs)) {
InitializeCriticalSection(cs);
}
-static V8_INLINE(void InitializeRecursiveNativeHandle(CRITICAL_SECTION* cs)) {
+static V8_INLINE(void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs)) {
InitializeCriticalSection(cs);
}
-static V8_INLINE(void DestroyNativeHandle(CRITICAL_SECTION* cs)) {
+static V8_INLINE(void DestroyNativeHandle(PCRITICAL_SECTION cs)) {
DeleteCriticalSection(cs);
}
-static V8_INLINE(void LockNativeHandle(CRITICAL_SECTION* cs)) {
+static V8_INLINE(void LockNativeHandle(PCRITICAL_SECTION cs)) {
EnterCriticalSection(cs);
}
-static V8_INLINE(void UnlockNativeHandle(CRITICAL_SECTION* cs)) {
+static V8_INLINE(void UnlockNativeHandle(PCRITICAL_SECTION cs)) {
LeaveCriticalSection(cs);
}
-static V8_INLINE(bool TryLockNativeHandle(CRITICAL_SECTION* cs)) {
+static V8_INLINE(bool TryLockNativeHandle(PCRITICAL_SECTION cs)) {
return TryEnterCriticalSection(cs);
}
@@ -149,18 +149,12 @@
void Mutex::Lock() {
LockNativeHandle(&native_handle_);
-#ifdef DEBUG
- ASSERT_EQ(0, level_);
- level_++;
-#endif
+ AssertUnheldAndMark();
}
void Mutex::Unlock() {
-#ifdef DEBUG
- ASSERT_EQ(1, level_);
- level_--;
-#endif
+ AssertHeldAndUnmark();
UnlockNativeHandle(&native_handle_);
}
@@ -169,10 +163,7 @@
if (!TryLockNativeHandle(&native_handle_)) {
return false;
}
-#ifdef DEBUG
- ASSERT_EQ(0, level_);
- level_++;
-#endif
+ AssertUnheldAndMark();
return true;
}
diff --git a/src/platform/mutex.h b/src/platform/mutex.h
index 1940542..c760c20 100644
--- a/src/platform/mutex.h
+++ b/src/platform/mutex.h
@@ -94,6 +94,22 @@
int level_;
#endif
+ V8_INLINE(void AssertHeldAndUnmark()) {
+#ifdef DEBUG
+ ASSERT_EQ(1, level_);
+ level_--;
+#endif
+ }
+
+ V8_INLINE(void AssertUnheldAndMark()) {
+#ifdef DEBUG
+ ASSERT_EQ(0, level_);
+ level_++;
+#endif
+ }
+
+ friend class ConditionVariable;
+
DISALLOW_COPY_AND_ASSIGN(Mutex);
};
diff --git a/src/platform/semaphore.cc b/src/platform/semaphore.cc
new file mode 100644
index 0000000..c3e5826
--- /dev/null
+++ b/src/platform/semaphore.cc
@@ -0,0 +1,214 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "platform/semaphore.h"
+
+#if V8_OS_MACOSX
+#include <mach/mach_init.h>
+#include <mach/task.h>
+#endif
+
+#include <cerrno>
+
+#include "checks.h"
+#include "platform/time.h"
+
+namespace v8 {
+namespace internal {
+
+#if V8_OS_MACOSX
+
+Semaphore::Semaphore(int count) {
+ kern_return_t result = semaphore_create(
+ mach_task_self(), &native_handle_, SYNC_POLICY_FIFO, count);
+ ASSERT_EQ(KERN_SUCCESS, result);
+ USE(result);
+}
+
+
+Semaphore::~Semaphore() {
+ kern_return_t result = semaphore_destroy(mach_task_self(), native_handle_);
+ ASSERT_EQ(KERN_SUCCESS, result);
+ USE(result);
+}
+
+
+void Semaphore::Signal() {
+ kern_return_t result = semaphore_signal(native_handle_);
+ ASSERT_EQ(KERN_SUCCESS, result);
+ USE(result);
+}
+
+
+void Semaphore::Wait() {
+ while (true) {
+ kern_return_t result = semaphore_wait(native_handle_);
+ if (result == KERN_SUCCESS) return; // Semaphore was signalled.
+ ASSERT_EQ(KERN_ABORTED, result);
+ }
+}
+
+
+bool Semaphore::WaitFor(const TimeDelta& rel_time) {
+ TimeTicks now = TimeTicks::Now();
+ TimeTicks end = now + rel_time;
+ while (true) {
+ mach_timespec_t ts;
+ if (now >= end) {
+ // Return immediately if semaphore was not signalled.
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ } else {
+ ts = (end - now).ToMachTimespec();
+ }
+ kern_return_t result = semaphore_timedwait(native_handle_, ts);
+ if (result == KERN_SUCCESS) return true; // Semaphore was signalled.
+ if (result == KERN_OPERATION_TIMED_OUT) return false; // Timeout.
+ ASSERT_EQ(KERN_ABORTED, result);
+ now = TimeTicks::Now();
+ }
+}
+
+#elif V8_OS_POSIX
+
+Semaphore::Semaphore(int count) {
+ ASSERT(count >= 0);
+ int result = sem_init(&native_handle_, 0, count);
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+Semaphore::~Semaphore() {
+ int result = sem_destroy(&native_handle_);
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+void Semaphore::Signal() {
+ int result = sem_post(&native_handle_);
+ ASSERT_EQ(0, result);
+ USE(result);
+}
+
+
+void Semaphore::Wait() {
+ while (true) {
+ int result = sem_wait(&native_handle_);
+ if (result == 0) return; // Semaphore was signalled.
+ // Signal caused spurious wakeup.
+ ASSERT_EQ(-1, result);
+ ASSERT_EQ(EINTR, errno);
+ }
+}
+
+
+bool Semaphore::WaitFor(const TimeDelta& rel_time) {
+ // Compute the time for end of timeout.
+ const Time time = Time::NowFromSystemTime() + rel_time;
+ const struct timespec ts = time.ToTimespec();
+
+ // Wait for semaphore signalled or timeout.
+ while (true) {
+ int result = sem_timedwait(&native_handle_, &ts);
+ if (result == 0) return true; // Semaphore was signalled.
+#if V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4)
+ if (result > 0) {
+ // sem_timedwait in glibc prior to 2.3.4 returns the errno instead of -1.
+ errno = result;
+ result = -1;
+ }
+#endif
+ if (result == -1 && errno == ETIMEDOUT) {
+ // Timed out while waiting for semaphore.
+ return false;
+ }
+ // Signal caused spurious wakeup.
+ ASSERT_EQ(-1, result);
+ ASSERT_EQ(EINTR, errno);
+ }
+}
+
+#elif V8_OS_WIN
+
+Semaphore::Semaphore(int count) {
+ ASSERT(count >= 0);
+ native_handle_ = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL);
+ ASSERT(native_handle_ != NULL);
+}
+
+
+Semaphore::~Semaphore() {
+ BOOL result = CloseHandle(native_handle_);
+ ASSERT(result);
+ USE(result);
+}
+
+
+void Semaphore::Signal() {
+ LONG dummy;
+ BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy);
+ ASSERT(result);
+ USE(result);
+}
+
+
+void Semaphore::Wait() {
+ DWORD result = WaitForSingleObject(native_handle_, INFINITE);
+ ASSERT(result == WAIT_OBJECT_0);
+ USE(result);
+}
+
+
+bool Semaphore::WaitFor(const TimeDelta& rel_time) {
+ TimeTicks now = TimeTicks::Now();
+ TimeTicks end = now + rel_time;
+ while (true) {
+ int64_t msec = (end - now).InMilliseconds();
+ if (msec >= static_cast<int64_t>(INFINITE)) {
+ DWORD result = WaitForSingleObject(native_handle_, INFINITE - 1);
+ if (result == WAIT_OBJECT_0) {
+ return true;
+ }
+ ASSERT(result == WAIT_TIMEOUT);
+ now = TimeTicks::Now();
+ } else {
+ DWORD result = WaitForSingleObject(
+ native_handle_, (msec < 0) ? 0 : static_cast<DWORD>(msec));
+ if (result == WAIT_TIMEOUT) {
+ return false;
+ }
+ ASSERT(result == WAIT_OBJECT_0);
+ return true;
+ }
+ }
+}
+
+#endif // V8_OS_MACOSX
+
+} } // namespace v8::internal
diff --git a/src/platform/semaphore.h b/src/platform/semaphore.h
new file mode 100644
index 0000000..221c7a3
--- /dev/null
+++ b/src/platform/semaphore.h
@@ -0,0 +1,126 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_SEMAPHORE_H_
+#define V8_PLATFORM_SEMAPHORE_H_
+
+#include "lazy-instance.h"
+#if V8_OS_WIN
+#include "win32-headers.h"
+#endif
+
+#if V8_OS_MACOSX
+#include <mach/semaphore.h> // NOLINT
+#elif V8_OS_POSIX
+#include <semaphore.h> // NOLINT
+#endif
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class TimeDelta;
+
+// ----------------------------------------------------------------------------
+// Semaphore
+//
+// A semaphore object is a synchronization object that maintains a count. The
+// count is decremented each time a thread completes a wait for the semaphore
+// object and incremented each time a thread signals the semaphore. When the
+// count reaches zero, threads waiting for the semaphore blocks until the
+// count becomes non-zero.
+
+class Semaphore V8_FINAL {
+ public:
+ explicit Semaphore(int count);
+ ~Semaphore();
+
+ // Increments the semaphore counter.
+ void Signal();
+
+ // Suspends the calling thread until the semaphore counter is non zero
+ // and then decrements the semaphore counter.
+ void Wait();
+
+ // Suspends the calling thread until the counter is non zero or the timeout
+ // time has passed. If timeout happens the return value is false and the
+ // counter is unchanged. Otherwise the semaphore counter is decremented and
+ // true is returned.
+ bool WaitFor(const TimeDelta& rel_time) V8_WARN_UNUSED_RESULT;
+
+#if V8_OS_MACOSX
+ typedef semaphore_t NativeHandle;
+#elif V8_OS_POSIX
+ typedef sem_t NativeHandle;
+#elif V8_OS_WIN
+ typedef HANDLE NativeHandle;
+#endif
+
+ NativeHandle& native_handle() V8_WARN_UNUSED_RESULT {
+ return native_handle_;
+ }
+ const NativeHandle& native_handle() const V8_WARN_UNUSED_RESULT {
+ return native_handle_;
+ }
+
+ private:
+ NativeHandle native_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(Semaphore);
+};
+
+
+// POD Semaphore initialized lazily (i.e. the first time Pointer() is called).
+// Usage:
+// // The following semaphore starts at 0.
+// static LazySemaphore<0>::type my_semaphore = LAZY_SEMAPHORE_INITIALIZER;
+//
+// void my_function() {
+// // Do something with my_semaphore.Pointer().
+// }
+//
+
+template <int N>
+struct CreateSemaphoreTrait {
+ static Semaphore* Create() {
+ return new Semaphore(N);
+ }
+};
+
+template <int N>
+struct LazySemaphore {
+ typedef typename LazyDynamicInstance<
+ Semaphore,
+ CreateSemaphoreTrait<N>,
+ ThreadSafeInitOnceTrait>::type type;
+};
+
+#define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER
+
+} } // namespace v8::internal
+
+#endif // V8_PLATFORM_SEMAPHORE_H_
diff --git a/src/platform/time.cc b/src/platform/time.cc
index 073ca1e..ea6dd2c 100644
--- a/src/platform/time.cc
+++ b/src/platform/time.cc
@@ -123,6 +123,51 @@
}
+#if V8_OS_MACOSX
+
+TimeDelta TimeDelta::FromMachTimespec(struct mach_timespec ts) {
+ ASSERT_GE(ts.tv_nsec, 0);
+ ASSERT_LT(ts.tv_nsec,
+ static_cast<long>(Time::kNanosecondsPerSecond)); // NOLINT
+ return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond +
+ ts.tv_nsec / Time::kNanosecondsPerMicrosecond);
+}
+
+
+struct mach_timespec TimeDelta::ToMachTimespec() const {
+ struct mach_timespec ts;
+ ASSERT(delta_ >= 0);
+ ts.tv_sec = delta_ / Time::kMicrosecondsPerSecond;
+ ts.tv_nsec = (delta_ % Time::kMicrosecondsPerSecond) *
+ Time::kNanosecondsPerMicrosecond;
+ return ts;
+}
+
+#endif // V8_OS_MACOSX
+
+
+#if V8_OS_POSIX
+
+TimeDelta TimeDelta::FromTimespec(struct timespec ts) {
+ ASSERT_GE(ts.tv_nsec, 0);
+ ASSERT_LT(ts.tv_nsec,
+ static_cast<long>(Time::kNanosecondsPerSecond)); // NOLINT
+ return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond +
+ ts.tv_nsec / Time::kNanosecondsPerMicrosecond);
+}
+
+
+struct timespec TimeDelta::ToTimespec() const {
+ struct timespec ts;
+ ts.tv_sec = delta_ / Time::kMicrosecondsPerSecond;
+ ts.tv_nsec = (delta_ % Time::kMicrosecondsPerSecond) *
+ Time::kNanosecondsPerMicrosecond;
+ return ts;
+}
+
+#endif // V8_OS_POSIX
+
+
#if V8_OS_WIN
// We implement time using the high-resolution timers so that we can get
@@ -246,6 +291,39 @@
}
+Time Time::FromTimespec(struct timespec ts) {
+ ASSERT(ts.tv_nsec >= 0);
+ ASSERT(ts.tv_nsec < static_cast<long>(kNanosecondsPerSecond)); // NOLINT
+ if (ts.tv_nsec == 0 && ts.tv_sec == 0) {
+ return Time();
+ }
+ if (ts.tv_nsec == static_cast<long>(kNanosecondsPerSecond - 1) && // NOLINT
+ ts.tv_sec == std::numeric_limits<time_t>::max()) {
+ return Max();
+ }
+ return Time(ts.tv_sec * kMicrosecondsPerSecond +
+ ts.tv_nsec / kNanosecondsPerMicrosecond);
+}
+
+
+struct timespec Time::ToTimespec() const {
+ struct timespec ts;
+ if (IsNull()) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ return ts;
+ }
+ if (IsMax()) {
+ ts.tv_sec = std::numeric_limits<time_t>::max();
+ ts.tv_nsec = static_cast<long>(kNanosecondsPerSecond - 1); // NOLINT
+ return ts;
+ }
+ ts.tv_sec = us_ / kMicrosecondsPerSecond;
+ ts.tv_nsec = (us_ % kMicrosecondsPerSecond) * kNanosecondsPerMicrosecond;
+ return ts;
+}
+
+
Time Time::FromTimeval(struct timeval tv) {
ASSERT(tv.tv_usec >= 0);
ASSERT(tv.tv_usec < static_cast<suseconds_t>(kMicrosecondsPerSecond));
diff --git a/src/platform/time.h b/src/platform/time.h
index 57b894d..3fed628 100644
--- a/src/platform/time.h
+++ b/src/platform/time.h
@@ -36,6 +36,8 @@
// Forward declarations.
extern "C" {
struct _FILETIME;
+struct mach_timespec;
+struct timespec;
struct timeval;
}
@@ -82,6 +84,14 @@
int64_t InMicroseconds() const { return delta_; }
int64_t InNanoseconds() const;
+ // Converts to/from Mach time specs.
+ static TimeDelta FromMachTimespec(struct mach_timespec ts);
+ struct mach_timespec ToMachTimespec() const;
+
+ // Converts to/from POSIX time specs.
+ static TimeDelta FromTimespec(struct timespec ts);
+ struct timespec ToTimespec() const;
+
TimeDelta& operator=(const TimeDelta& other) {
delta_ = other.delta_;
return *this;
@@ -212,6 +222,10 @@
// with which we might compare it.
static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
+ // Converts to/from POSIX time specs.
+ static Time FromTimespec(struct timespec ts);
+ struct timespec ToTimespec() const;
+
// Converts to/from POSIX time values.
static Time FromTimeval(struct timeval tv);
struct timeval ToTimeval() const;
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index def0097..19090a0 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -442,7 +442,7 @@
CpuProfilesCollection::CpuProfilesCollection()
- : current_profiles_semaphore_(OS::CreateSemaphore(1)) {
+ : current_profiles_semaphore_(1) {
}
@@ -457,7 +457,6 @@
CpuProfilesCollection::~CpuProfilesCollection() {
- delete current_profiles_semaphore_;
finished_profiles_.Iterate(DeleteCpuProfile);
current_profiles_.Iterate(DeleteCpuProfile);
code_entries_.Iterate(DeleteCodeEntry);
@@ -467,20 +466,20 @@
bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid,
bool record_samples) {
ASSERT(uid > 0);
- current_profiles_semaphore_->Wait();
+ current_profiles_semaphore_.Wait();
if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
- current_profiles_semaphore_->Signal();
+ current_profiles_semaphore_.Signal();
return false;
}
for (int i = 0; i < current_profiles_.length(); ++i) {
if (strcmp(current_profiles_[i]->title(), title) == 0) {
// Ignore attempts to start profile with the same title.
- current_profiles_semaphore_->Signal();
+ current_profiles_semaphore_.Signal();
return false;
}
}
current_profiles_.Add(new CpuProfile(title, uid, record_samples));
- current_profiles_semaphore_->Signal();
+ current_profiles_semaphore_.Signal();
return true;
}
@@ -488,14 +487,14 @@
CpuProfile* CpuProfilesCollection::StopProfiling(const char* title) {
const int title_len = StrLength(title);
CpuProfile* profile = NULL;
- current_profiles_semaphore_->Wait();
+ current_profiles_semaphore_.Wait();
for (int i = current_profiles_.length() - 1; i >= 0; --i) {
if (title_len == 0 || strcmp(current_profiles_[i]->title(), title) == 0) {
profile = current_profiles_.Remove(i);
break;
}
}
- current_profiles_semaphore_->Signal();
+ current_profiles_semaphore_.Signal();
if (profile == NULL) return NULL;
profile->CalculateTotalTicksAndSamplingRate();
@@ -531,11 +530,11 @@
// As starting / stopping profiles is rare relatively to this
// method, we don't bother minimizing the duration of lock holding,
// e.g. copying contents of the list to a local vector.
- current_profiles_semaphore_->Wait();
+ current_profiles_semaphore_.Wait();
for (int i = 0; i < current_profiles_.length(); ++i) {
current_profiles_[i]->AddPath(path);
}
- current_profiles_semaphore_->Signal();
+ current_profiles_semaphore_.Signal();
}
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 5edcac8..70f00de 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -312,7 +312,7 @@
// Accessed by VM thread and profile generator thread.
List<CpuProfile*> current_profiles_;
- Semaphore* current_profiles_semaphore_;
+ Semaphore current_profiles_semaphore_;
DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection);
};
diff --git a/src/property.h b/src/property.h
index 19425ed..094590e 100644
--- a/src/property.h
+++ b/src/property.h
@@ -225,14 +225,14 @@
void HandlerResult(JSProxy* proxy) {
lookup_type_ = HANDLER_TYPE;
holder_ = proxy;
- details_ = PropertyDetails(NONE, HANDLER, Representation::None());
+ details_ = PropertyDetails(NONE, HANDLER, Representation::Tagged());
cacheable_ = false;
}
void InterceptorResult(JSObject* holder) {
lookup_type_ = INTERCEPTOR_TYPE;
holder_ = holder;
- details_ = PropertyDetails(NONE, INTERCEPTOR, Representation::None());
+ details_ = PropertyDetails(NONE, INTERCEPTOR, Representation::Tagged());
}
void NotFound() {
diff --git a/src/runtime.cc b/src/runtime.cc
index 4830faf..d183a6b 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2621,8 +2621,8 @@
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
bool threw = false;
- Handle<Object> delegate =
- Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
+ Handle<Object> delegate = Execution::TryGetFunctionDelegate(
+ isolate, Handle<JSReceiver>(callable), &threw);
if (threw) return Failure::Exception();
callable = JSFunction::cast(*delegate);
}
@@ -2640,8 +2640,8 @@
if (!callable->IsJSFunction()) {
HandleScope scope(isolate);
bool threw = false;
- Handle<Object> delegate =
- Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
+ Handle<Object> delegate = Execution::TryGetFunctionDelegate(
+ isolate, Handle<JSReceiver>(callable), &threw);
if (threw) return Failure::Exception();
callable = JSFunction::cast(*delegate);
}
@@ -4799,7 +4799,7 @@
} else {
bool has_pending_exception = false;
Handle<Object> converted =
- Execution::ToString(key, &has_pending_exception);
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
name = Handle<Name>::cast(converted);
}
@@ -4841,7 +4841,7 @@
} else {
bool has_pending_exception = false;
Handle<Object> converted =
- Execution::ToString(key, &has_pending_exception);
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
name = Handle<Name>::cast(converted);
}
@@ -5139,7 +5139,7 @@
if (object->IsJSProxy()) {
bool has_pending_exception = false;
Handle<Object> name = key->IsSymbol()
- ? key : Execution::ToString(key, &has_pending_exception);
+ ? key : Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
return JSProxy::cast(*object)->SetProperty(
Name::cast(*name), *value, attr, strict_mode);
@@ -5168,7 +5168,8 @@
if (js_object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
bool has_exception;
- Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ Handle<Object> number =
+ Execution::ToNumber(isolate, value, &has_exception);
if (has_exception) return Failure::Exception();
value = number;
}
@@ -5187,7 +5188,8 @@
if (js_object->HasExternalArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
bool has_exception;
- Handle<Object> number = Execution::ToNumber(value, &has_exception);
+ Handle<Object> number =
+ Execution::ToNumber(isolate, value, &has_exception);
if (has_exception) return Failure::Exception();
value = number;
}
@@ -5204,7 +5206,8 @@
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+ Handle<Object> converted =
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
Handle<String> name = Handle<String>::cast(converted);
@@ -5255,7 +5258,8 @@
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+ Handle<Object> converted =
+ Execution::ToString(isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
Handle<String> name = Handle<String>::cast(converted);
@@ -5298,7 +5302,8 @@
} else {
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
- Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
+ Handle<Object> converted = Execution::ToString(
+ isolate, key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
name = Handle<String>::cast(converted);
}
@@ -5890,7 +5895,7 @@
HandleScope scope(isolate);
bool exception = false;
Handle<Object> converted =
- Execution::ToString(args.at<Object>(0), &exception);
+ Execution::ToString(isolate, args.at<Object>(0), &exception);
if (exception) return Failure::Exception();
Handle<String> key = Handle<String>::cast(converted);
@@ -8151,7 +8156,8 @@
if (!bound_function->IsJSFunction()) {
bool exception_thrown;
- bound_function = Execution::TryGetConstructorDelegate(bound_function,
+ bound_function = Execution::TryGetConstructorDelegate(isolate,
+ bound_function,
&exception_thrown);
if (exception_thrown) return Failure::Exception();
}
@@ -8346,7 +8352,7 @@
HandleScope handle_scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- ASSERT(V8::UseCrankshaft() && FLAG_concurrent_recompilation);
+ ASSERT(isolate->use_crankshaft() && FLAG_concurrent_recompilation);
isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
return function->code();
}
@@ -8532,7 +8538,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) {
HandleScope scope(isolate);
RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
- if (!V8::UseCrankshaft()) {
+ if (!isolate->use_crankshaft()) {
return Smi::FromInt(4); // 4 == "never".
}
bool sync_with_compiler_thread = true;
@@ -8781,7 +8787,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetFunctionDelegate(args.at<Object>(0));
+ return *Execution::GetFunctionDelegate(isolate, args.at<Object>(0));
}
@@ -8789,7 +8795,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetConstructorDelegate(args.at<Object>(0));
+ return *Execution::GetConstructorDelegate(isolate, args.at<Object>(0));
}
@@ -10576,7 +10582,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
- return Execution::DebugBreakHelper();
+ return Execution::DebugBreakHelper(isolate);
}
@@ -12076,6 +12082,8 @@
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
JavaScriptFrameIterator frame_it(isolate, id);
+ RUNTIME_ASSERT(!frame_it.done());
+
JavaScriptFrame* frame = frame_it.frame();
Handle<JSFunction> fun =
@@ -12095,11 +12103,28 @@
BreakLocationIterator break_location_iterator(debug_info,
ALL_BREAK_LOCATIONS);
- break_location_iterator.FindBreakLocationFromAddress(frame->pc());
+ break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
int current_statement_pos = break_location_iterator.statement_position();
while (!break_location_iterator.Done()) {
+ bool accept;
if (break_location_iterator.pc() > frame->pc()) {
+ accept = true;
+ } else {
+ StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
+ // The break point is near our pc. Could be a step-in possibility,
+ // that is currently taken by active debugger call.
+ if (break_frame_id == StackFrame::NO_ID) {
+ // We are not stepping.
+ accept = false;
+ } else {
+ JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
+ // If our frame is a top frame and we are stepping, we can do step-in
+ // at this place.
+ accept = additional_frame_it.frame()->id() == id;
+ }
+ }
+ if (accept) {
if (break_location_iterator.IsStepInLocation(isolate)) {
Smi* position_value = Smi::FromInt(break_location_iterator.position());
JSObject::SetElement(array, len,
@@ -12668,7 +12693,7 @@
Handle<Object> context_extension(args[5], isolate);
// Handle the processing of break.
- DisableBreak disable_break_save(disable_break);
+ DisableBreak disable_break_save(isolate, disable_break);
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -12735,7 +12760,7 @@
Handle<Object> context_extension(args[3], isolate);
// Handle the processing of break.
- DisableBreak disable_break_save(disable_break);
+ DisableBreak disable_break_save(isolate, disable_break);
// Enter the top context from before the debugger was invoked.
SaveContext save(isolate);
@@ -13403,7 +13428,7 @@
result = Execution::Call(function, isolate->global_object(), 0, NULL,
&pending_exception);
} else {
- EnterDebugger enter_debugger;
+ EnterDebugger enter_debugger(isolate);
result = Execution::Call(function, isolate->global_object(), 0, NULL,
&pending_exception);
}
@@ -13696,7 +13721,8 @@
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
bool has_pending_exception = false;
- Handle<Object> value = Execution::ToNumber(date, &has_pending_exception);
+ Handle<Object> value =
+ Execution::ToNumber(isolate, date, &has_pending_exception);
if (has_pending_exception) {
ASSERT(isolate->has_pending_exception());
return Failure::Exception();
@@ -13736,7 +13762,8 @@
bool has_pending_exception = false;
Handle<JSDate> result = Handle<JSDate>::cast(
- Execution::NewDate(static_cast<double>(date), &has_pending_exception));
+ Execution::NewDate(
+ isolate, static_cast<double>(date), &has_pending_exception));
if (has_pending_exception) {
ASSERT(isolate->has_pending_exception());
return Failure::Exception();
@@ -13798,7 +13825,8 @@
CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
bool has_pending_exception = false;
- Handle<Object> value = Execution::ToNumber(number, &has_pending_exception);
+ Handle<Object> value = Execution::ToNumber(
+ isolate, number, &has_pending_exception);
if (has_pending_exception) {
ASSERT(isolate->has_pending_exception());
return Failure::Exception();
diff --git a/src/sweeper-thread.cc b/src/sweeper-thread.cc
index ede567a..58c684a 100644
--- a/src/sweeper-thread.cc
+++ b/src/sweeper-thread.cc
@@ -42,9 +42,9 @@
isolate_(isolate),
heap_(isolate->heap()),
collector_(heap_->mark_compact_collector()),
- start_sweeping_semaphore_(OS::CreateSemaphore(0)),
- end_sweeping_semaphore_(OS::CreateSemaphore(0)),
- stop_semaphore_(OS::CreateSemaphore(0)),
+ start_sweeping_semaphore_(0),
+ end_sweeping_semaphore_(0),
+ stop_semaphore_(0),
free_list_old_data_space_(heap_->paged_space(OLD_DATA_SPACE)),
free_list_old_pointer_space_(heap_->paged_space(OLD_POINTER_SPACE)),
private_free_list_old_data_space_(heap_->paged_space(OLD_DATA_SPACE)),
@@ -61,10 +61,10 @@
DisallowHandleDereference no_deref;
while (true) {
- start_sweeping_semaphore_->Wait();
+ start_sweeping_semaphore_.Wait();
if (Acquire_Load(&stop_thread_)) {
- stop_semaphore_->Signal();
+ stop_semaphore_.Signal();
return;
}
@@ -74,7 +74,7 @@
collector_->SweepInParallel(heap_->old_pointer_space(),
&private_free_list_old_pointer_space_,
&free_list_old_pointer_space_);
- end_sweeping_semaphore_->Signal();
+ end_sweeping_semaphore_.Signal();
}
}
@@ -91,18 +91,18 @@
void SweeperThread::Stop() {
Release_Store(&stop_thread_, static_cast<AtomicWord>(true));
- start_sweeping_semaphore_->Signal();
- stop_semaphore_->Wait();
+ start_sweeping_semaphore_.Signal();
+ stop_semaphore_.Wait();
Join();
}
void SweeperThread::StartSweeping() {
- start_sweeping_semaphore_->Signal();
+ start_sweeping_semaphore_.Signal();
}
void SweeperThread::WaitForSweeperThread() {
- end_sweeping_semaphore_->Wait();
+ end_sweeping_semaphore_.Wait();
}
} } // namespace v8::internal
diff --git a/src/sweeper-thread.h b/src/sweeper-thread.h
index a170982..c36cfc3 100644
--- a/src/sweeper-thread.h
+++ b/src/sweeper-thread.h
@@ -43,6 +43,7 @@
class SweeperThread : public Thread {
public:
explicit SweeperThread(Isolate* isolate);
+ ~SweeperThread() {}
void Run();
void Stop();
@@ -50,19 +51,13 @@
void WaitForSweeperThread();
intptr_t StealMemory(PagedSpace* space);
- ~SweeperThread() {
- delete start_sweeping_semaphore_;
- delete end_sweeping_semaphore_;
- delete stop_semaphore_;
- }
-
private:
Isolate* isolate_;
Heap* heap_;
MarkCompactCollector* collector_;
- Semaphore* start_sweeping_semaphore_;
- Semaphore* end_sweeping_semaphore_;
- Semaphore* stop_semaphore_;
+ Semaphore start_sweeping_semaphore_;
+ Semaphore end_sweeping_semaphore_;
+ Semaphore stop_semaphore_;
FreeList free_list_old_data_space_;
FreeList free_list_old_pointer_space_;
FreeList private_free_list_old_data_space_;
diff --git a/src/v8-counters.cc b/src/v8-counters.cc
index 905e178..6711c80 100644
--- a/src/v8-counters.cc
+++ b/src/v8-counters.cc
@@ -49,31 +49,31 @@
#undef HM
#define SC(name, caption) \
- name##_ = StatsCounter("c:" #caption);
+ name##_ = StatsCounter(isolate, "c:" #caption);
STATS_COUNTER_LIST_1(SC)
STATS_COUNTER_LIST_2(SC)
#undef SC
#define SC(name) \
- count_of_##name##_ = StatsCounter("c:" "V8.CountOf_" #name); \
- size_of_##name##_ = StatsCounter("c:" "V8.SizeOf_" #name);
+ count_of_##name##_ = StatsCounter(isolate, "c:" "V8.CountOf_" #name); \
+ size_of_##name##_ = StatsCounter(isolate, "c:" "V8.SizeOf_" #name);
INSTANCE_TYPE_LIST(SC)
#undef SC
#define SC(name) \
count_of_CODE_TYPE_##name##_ = \
- StatsCounter("c:" "V8.CountOf_CODE_TYPE-" #name); \
+ StatsCounter(isolate, "c:" "V8.CountOf_CODE_TYPE-" #name); \
size_of_CODE_TYPE_##name##_ = \
- StatsCounter("c:" "V8.SizeOf_CODE_TYPE-" #name);
+ StatsCounter(isolate, "c:" "V8.SizeOf_CODE_TYPE-" #name);
CODE_KIND_LIST(SC)
#undef SC
#define SC(name) \
count_of_FIXED_ARRAY_##name##_ = \
- StatsCounter("c:" "V8.CountOf_FIXED_ARRAY-" #name); \
+ StatsCounter(isolate, "c:" "V8.CountOf_FIXED_ARRAY-" #name); \
size_of_FIXED_ARRAY_##name##_ = \
- StatsCounter("c:" "V8.SizeOf_FIXED_ARRAY-" #name);
+ StatsCounter(isolate, "c:" "V8.SizeOf_FIXED_ARRAY-" #name);
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
#undef SC
}
diff --git a/src/v8.cc b/src/v8.cc
index 7d2294e..f2aa837 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -50,11 +50,8 @@
V8_DECLARE_ONCE(init_once);
-bool V8::is_running_ = false;
bool V8::has_been_set_up_ = false;
bool V8::has_been_disposed_ = false;
-bool V8::has_fatal_error_ = false;
-bool V8::use_crankshaft_ = true;
List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
@@ -80,26 +77,17 @@
ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
i::Isolate::Current());
- if (IsDead()) return false;
-
Isolate* isolate = Isolate::Current();
+ if (isolate->IsDead()) return false;
if (isolate->IsInitialized()) return true;
- is_running_ = true;
has_been_set_up_ = true;
- has_fatal_error_ = false;
has_been_disposed_ = false;
return isolate->Init(des);
}
-void V8::SetFatalError() {
- is_running_ = false;
- has_fatal_error_ = true;
-}
-
-
void V8::TearDown() {
Isolate* isolate = Isolate::Current();
ASSERT(isolate->IsDefaultIsolate());
@@ -118,7 +106,6 @@
RegisteredExtension::UnregisterAll();
Isolate::GlobalTearDown();
- is_running_ = false;
has_been_disposed_ = true;
delete call_completed_callbacks_;
@@ -318,9 +305,6 @@
OS::SetUp();
Sampler::SetUp();
CPU::SetUp();
- use_crankshaft_ = FLAG_crankshaft
- && !Serializer::enabled()
- && CPU::SupportsCrankshaft();
OS::PostSetUp();
ElementsAccessor::InitializeOncePerProcess();
LOperand::SetUpCaches();
diff --git a/src/v8.h b/src/v8.h
index 47893e8..707482f 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -82,12 +82,6 @@
// empty heap.
static bool Initialize(Deserializer* des);
static void TearDown();
- static bool IsRunning() { return is_running_; }
- static bool UseCrankshaft() { return use_crankshaft_; }
- // To be dead you have to have lived
- // TODO(isolates): move IsDead to Isolate.
- static bool IsDead() { return has_fatal_error_ || has_been_disposed_; }
- static void SetFatalError();
// Report process out of memory. Implementation found in api.cc.
static void FatalProcessOutOfMemory(const char* location,
@@ -131,18 +125,11 @@
static void InitializeOncePerProcessImpl();
static void InitializeOncePerProcess();
- // True if engine is currently running
- static bool is_running_;
// True if V8 has ever been run
static bool has_been_set_up_;
- // True if error has been signaled for current engine
- // (reset to false if engine is restarted)
- static bool has_fatal_error_;
// True if engine has been shut down
// (reset if engine is restarted)
static bool has_been_disposed_;
- // True if we are using the crankshaft optimizing compiler.
- static bool use_crankshaft_;
// List of callbacks when a Call completes.
static List<CallCompletedCallback>* call_completed_callbacks_;
// Allocator for external array buffers.
diff --git a/src/version.cc b/src/version.cc
index 953f90f..5bc3a06 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
#define MINOR_VERSION 21
-#define BUILD_NUMBER 8
+#define BUILD_NUMBER 9
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 93d9aac..7d1f59a 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -61,7 +61,7 @@
// Print the code after compiling it.
static void PrintCode(Handle<Code> code, CompilationInfo* info);
- static bool ShouldGenerateLog(Expression* type);
+ static bool ShouldGenerateLog(Isolate* isolate, Expression* type);
static bool RecordPositions(MacroAssembler* masm,
int pos,
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index 3509794..acf2dc1 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -332,10 +332,10 @@
private:
enum OperandSize {
- BYTE_SIZE = 0,
- WORD_SIZE = 1,
- DOUBLEWORD_SIZE = 2,
- QUADWORD_SIZE = 3
+ OPERAND_BYTE_SIZE = 0,
+ OPERAND_WORD_SIZE = 1,
+ OPERAND_DOUBLEWORD_SIZE = 2,
+ OPERAND_QUADWORD_SIZE = 3
};
const NameConverter& converter_;
@@ -369,10 +369,10 @@
bool rex_w() { return (rex_ & 0x08) != 0; }
OperandSize operand_size() {
- if (byte_size_operand_) return BYTE_SIZE;
- if (rex_w()) return QUADWORD_SIZE;
- if (operand_size_ != 0) return WORD_SIZE;
- return DOUBLEWORD_SIZE;
+ if (byte_size_operand_) return OPERAND_BYTE_SIZE;
+ if (rex_w()) return OPERAND_QUADWORD_SIZE;
+ if (operand_size_ != 0) return OPERAND_WORD_SIZE;
+ return OPERAND_DOUBLEWORD_SIZE;
}
char operand_size_code() {
@@ -562,19 +562,19 @@
int64_t value;
int count;
switch (size) {
- case BYTE_SIZE:
+ case OPERAND_BYTE_SIZE:
value = *data;
count = 1;
break;
- case WORD_SIZE:
+ case OPERAND_WORD_SIZE:
value = *reinterpret_cast<int16_t*>(data);
count = 2;
break;
- case DOUBLEWORD_SIZE:
+ case OPERAND_DOUBLEWORD_SIZE:
value = *reinterpret_cast<uint32_t*>(data);
count = 4;
break;
- case QUADWORD_SIZE:
+ case OPERAND_QUADWORD_SIZE:
value = *reinterpret_cast<int32_t*>(data);
count = 4;
break;
@@ -682,7 +682,8 @@
AppendToBuffer("%s%c ", mnem, operand_size_code());
int count = PrintRightOperand(data + 1);
AppendToBuffer(",0x");
- OperandSize immediate_size = byte_size_immediate ? BYTE_SIZE : operand_size();
+ OperandSize immediate_size =
+ byte_size_immediate ? OPERAND_BYTE_SIZE : operand_size();
count += PrintImmediate(data + 1 + count, immediate_size);
return 1 + count;
}
@@ -1415,15 +1416,15 @@
case MOVE_REG_INSTR: {
byte* addr = NULL;
switch (operand_size()) {
- case WORD_SIZE:
+ case OPERAND_WORD_SIZE:
addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
data += 3;
break;
- case DOUBLEWORD_SIZE:
+ case OPERAND_DOUBLEWORD_SIZE:
addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
data += 5;
break;
- case QUADWORD_SIZE:
+ case OPERAND_QUADWORD_SIZE:
addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
data += 9;
break;
@@ -1628,11 +1629,11 @@
AppendToBuffer("mov%c %s, ",
operand_size_code(),
NameOfCPURegister(reg));
- data += PrintImmediate(data, DOUBLEWORD_SIZE);
+ data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE);
} else {
AppendToBuffer("movb %s, ",
NameOfByteCPURegister(reg));
- data += PrintImmediate(data, BYTE_SIZE);
+ data += PrintImmediate(data, OPERAND_BYTE_SIZE);
}
break;
}
@@ -1661,7 +1662,7 @@
case 0xA1: // Fall through.
case 0xA3:
switch (operand_size()) {
- case DOUBLEWORD_SIZE: {
+ case OPERAND_DOUBLEWORD_SIZE: {
const char* memory_location = NameOfAddress(
reinterpret_cast<byte*>(
*reinterpret_cast<int32_t*>(data + 1)));
@@ -1673,7 +1674,7 @@
data += 5;
break;
}
- case QUADWORD_SIZE: {
+ case OPERAND_QUADWORD_SIZE: {
// New x64 instruction mov rax,(imm_64).
const char* memory_location = NameOfAddress(
*reinterpret_cast<byte**>(data + 1));
@@ -1699,15 +1700,15 @@
case 0xA9: {
int64_t value = 0;
switch (operand_size()) {
- case WORD_SIZE:
+ case OPERAND_WORD_SIZE:
value = *reinterpret_cast<uint16_t*>(data + 1);
data += 3;
break;
- case DOUBLEWORD_SIZE:
+ case OPERAND_DOUBLEWORD_SIZE:
value = *reinterpret_cast<uint32_t*>(data + 1);
data += 5;
break;
- case QUADWORD_SIZE:
+ case OPERAND_QUADWORD_SIZE:
value = *reinterpret_cast<int32_t*>(data + 1);
data += 5;
break;
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 54472c2..c182dd0 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -3243,7 +3243,7 @@
// 2 (array): Arguments to the format string.
ZoneList<Expression*>* args = expr->arguments();
ASSERT_EQ(args->length(), 3);
- if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
+ if (CodeGenerator::ShouldGenerateLog(isolate(), args->at(0))) {
VisitForStackValue(args->at(1));
VisitForStackValue(args->at(2));
__ CallRuntime(Runtime::kLog, 2);
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 051d382..ce01e3d 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -55,6 +55,7 @@
'test-bignum-dtoa.cc',
'test-circular-queue.cc',
'test-compiler.cc',
+ 'test-condition-variable.cc',
'test-conversions.cc',
'test-cpu.cc',
'test-cpu-profiler.cc',
@@ -80,7 +81,6 @@
'test-heap-profiler.cc',
'test-list.cc',
'test-liveedit.cc',
- 'test-lock.cc',
'test-lockers.cc',
'test-log.cc',
'test-mark-compact.cc',
@@ -93,6 +93,7 @@
'test-random.cc',
'test-regexp.cc',
'test-reloc-info.cc',
+ 'test-semaphore.cc',
'test-serialize.cc',
'test-sockets.cc',
'test-spaces.cc',
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index 193126a..7fb25e8 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -144,10 +144,10 @@
explicit ApiTestFuzzer(int num)
: Thread("ApiTestFuzzer"),
test_number_(num),
- gate_(v8::internal::OS::CreateSemaphore(0)),
+ gate_(0),
active_(true) {
}
- ~ApiTestFuzzer() { delete gate_; }
+ ~ApiTestFuzzer() {}
static bool fuzzing_;
static int tests_being_run_;
@@ -155,11 +155,11 @@
static int active_tests_;
static bool NextThread();
int test_number_;
- v8::internal::Semaphore* gate_;
+ v8::internal::Semaphore gate_;
bool active_;
void ContextSwitch();
static int GetNextTestNumber();
- static v8::internal::Semaphore* all_tests_done_;
+ static v8::internal::Semaphore all_tests_done_;
};
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 91f377a..4468e65 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1828,7 +1828,17 @@
void InterceptorSetter(Local<String> name,
Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
- // Intercept accesses that set certain integer values.
+ // Intercept accesses that set certain integer values, for which the name does
+ // not start with 'accessor_'.
+ String::Utf8Value utf8(name);
+ char* name_str = *utf8;
+ char prefix[] = "accessor_";
+ int i;
+ for (i = 0; name_str[i] && prefix[i]; ++i) {
+ if (name_str[i] != prefix[i]) break;
+ }
+ if (!prefix[i]) return;
+
if (value->IsInt32() && value->Int32Value() < 10000) {
Handle<Object> self = info.This();
self->SetHiddenValue(name, value);
@@ -3108,7 +3118,7 @@
v8::HandleScope scope(isolate);
CHECK_EQ(v8::Local<String>::New(isolate, global)->Length(), 6);
}
- global.Dispose(isolate);
+ global.Dispose();
CHECK_EQ(global_handles->global_handles_count(), initial_handle_count - 1);
}
@@ -3242,7 +3252,7 @@
WeakCallCounter* counter) {
CHECK_EQ(1234, counter->id());
counter->increment();
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -3315,8 +3325,8 @@
root.MakeWeak(&counter, &WeakPointerCallback);
// But make children strong roots---all the objects (except for children)
// should be collectable now.
- g1c1.ClearWeak(iso);
- g2c1.ClearWeak(iso);
+ g1c1.ClearWeak();
+ g2c1.ClearWeak();
// Groups are deleted, rebuild groups.
{
@@ -3366,29 +3376,29 @@
g1s2.Reset(iso, Object::New());
g1s1.MakeWeak(&counter, &WeakPointerCallback);
g1s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g1s1.IsWeak(iso));
- CHECK(g1s2.IsWeak(iso));
+ CHECK(g1s1.IsWeak());
+ CHECK(g1s2.IsWeak());
g2s1.Reset(iso, Object::New());
g2s2.Reset(iso, Object::New());
g2s1.MakeWeak(&counter, &WeakPointerCallback);
g2s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g2s1.IsWeak(iso));
- CHECK(g2s2.IsWeak(iso));
+ CHECK(g2s1.IsWeak());
+ CHECK(g2s2.IsWeak());
g3s1.Reset(iso, Object::New());
g3s2.Reset(iso, Object::New());
g3s1.MakeWeak(&counter, &WeakPointerCallback);
g3s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g3s1.IsWeak(iso));
- CHECK(g3s2.IsWeak(iso));
+ CHECK(g3s1.IsWeak());
+ CHECK(g3s2.IsWeak());
g4s1.Reset(iso, Object::New());
g4s2.Reset(iso, Object::New());
g4s1.MakeWeak(&counter, &WeakPointerCallback);
g4s2.MakeWeak(&counter, &WeakPointerCallback);
- CHECK(g4s1.IsWeak(iso));
- CHECK(g4s2.IsWeak(iso));
+ CHECK(g4s1.IsWeak());
+ CHECK(g4s2.IsWeak());
}
Persistent<Value> root(iso, g1s1); // make a root.
@@ -3490,19 +3500,19 @@
// Make a root.
Persistent<Value> root(iso, g1s1);
- root.MarkPartiallyDependent(iso);
+ root.MarkPartiallyDependent();
// Connect groups. We're building the following cycle:
// G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
// groups.
{
HandleScope handle_scope(iso);
- g1s1.MarkPartiallyDependent(iso);
- g1s2.MarkPartiallyDependent(iso);
- g2s1.MarkPartiallyDependent(iso);
- g2s2.MarkPartiallyDependent(iso);
- g3s1.MarkPartiallyDependent(iso);
- g3s2.MarkPartiallyDependent(iso);
+ g1s1.MarkPartiallyDependent();
+ g1s2.MarkPartiallyDependent();
+ g2s1.MarkPartiallyDependent();
+ g2s2.MarkPartiallyDependent();
+ g3s1.MarkPartiallyDependent();
+ g3s2.MarkPartiallyDependent();
iso->SetObjectGroupId(g1s1, UniqueId(1));
iso->SetObjectGroupId(g1s2, UniqueId(1));
Local<Object>::New(iso, g1s1.As<Object>())->Set(
@@ -3526,18 +3536,17 @@
// Weaken the root.
root.MakeWeak(&counter, &WeakPointerCallback);
- root.MarkPartiallyDependent(iso);
+ root.MarkPartiallyDependent();
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
// Groups are deleted, rebuild groups.
{
HandleScope handle_scope(iso);
- g1s1.MarkPartiallyDependent(isolate);
- g1s2.MarkPartiallyDependent(isolate);
- g2s1.MarkPartiallyDependent(isolate);
- g2s2.MarkPartiallyDependent(isolate);
- g3s1.MarkPartiallyDependent(isolate);
- g3s2.MarkPartiallyDependent(isolate);
+ g1s1.MarkPartiallyDependent();
+ g1s2.MarkPartiallyDependent();
+ g2s1.MarkPartiallyDependent();
+ g2s2.MarkPartiallyDependent();
+ g3s1.MarkPartiallyDependent();
+ g3s2.MarkPartiallyDependent();
iso->SetObjectGroupId(g1s1, UniqueId(1));
iso->SetObjectGroupId(g1s2, UniqueId(1));
Local<Object>::New(iso, g1s1.As<Object>())->Set(
@@ -4895,7 +4904,7 @@
v8::Handle<v8::Object> obj = v8::Object::New();
v8::Persistent<v8::Object> alias(isolate, obj);
CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj));
- alias.Dispose(isolate);
+ alias.Dispose();
}
@@ -5210,7 +5219,7 @@
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue));
- xValue.Dispose(context->GetIsolate());
+ xValue.Dispose();
xValue.Clear();
}
}
@@ -5227,7 +5236,7 @@
CHECK(xValue.IsEmpty());
script->Run();
CHECK_EQ(v8_num(4), Local<Value>::New(v8::Isolate::GetCurrent(), xValue));
- xValue.Dispose(context->GetIsolate());
+ xValue.Dispose();
xValue.Clear();
}
}
@@ -6602,7 +6611,7 @@
class Whammy {
public:
explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
- ~Whammy() { script_.Dispose(isolate_); }
+ ~Whammy() { script_.Dispose(); }
v8::Handle<Script> getScript() {
if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
return Local<Script>::New(isolate_, script_);
@@ -6620,7 +6629,7 @@
v8::Persistent<v8::Value>* obj,
Snorkel* snorkel) {
delete snorkel;
- obj->ClearWeak(isolate);
+ obj->ClearWeak();
}
void WhammyPropertyGetter(Local<String> name,
@@ -6676,7 +6685,7 @@
static void DisposeAndSetFlag(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->Dispose(isolate);
+ obj->Dispose();
*(data) = true;
}
@@ -6699,10 +6708,10 @@
bool object_b_disposed = false;
object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag);
- CHECK(!object_b.IsIndependent(iso));
- object_a.MarkIndependent(iso);
- object_b.MarkIndependent(iso);
- CHECK(object_b.IsIndependent(iso));
+ CHECK(!object_b.IsIndependent());
+ object_a.MarkIndependent();
+ object_b.MarkIndependent();
+ CHECK(object_b.IsIndependent());
HEAP->PerformScavenge();
CHECK(object_a_disposed);
CHECK(object_b_disposed);
@@ -6722,7 +6731,7 @@
static void ForceScavenge(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->Dispose(isolate);
+ obj->Dispose();
*(data) = true;
InvokeScavenge();
}
@@ -6731,7 +6740,7 @@
static void ForceMarkSweep(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->Dispose(isolate);
+ obj->Dispose();
*(data) = true;
InvokeMarkSweep();
}
@@ -6760,7 +6769,7 @@
}
bool disposed = false;
object.MakeWeak(&disposed, gc_forcing_callback[inner_gc]);
- object.MarkIndependent(isolate);
+ object.MarkIndependent();
invoke_gc[outer_gc]();
CHECK(disposed);
}
@@ -6771,7 +6780,7 @@
static void RevivingCallback(v8::Isolate* isolate,
v8::Persistent<v8::Object>* obj,
bool* data) {
- obj->ClearWeak(isolate);
+ obj->ClearWeak();
*(data) = true;
}
@@ -6793,7 +6802,7 @@
}
bool revived = false;
object.MakeWeak(&revived, &RevivingCallback);
- object.MarkIndependent(isolate);
+ object.MarkIndependent();
HEAP->PerformScavenge();
CHECK(revived);
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
@@ -12237,8 +12246,7 @@
bool ApiTestFuzzer::fuzzing_ = false;
-i::Semaphore* ApiTestFuzzer::all_tests_done_=
- i::OS::CreateSemaphore(0);
+i::Semaphore ApiTestFuzzer::all_tests_done_(0);
int ApiTestFuzzer::active_tests_;
int ApiTestFuzzer::tests_being_run_;
int ApiTestFuzzer::current_;
@@ -12269,14 +12277,14 @@
RegisterThreadedTest::nth(test_position)->name());
}
current_ = test_position;
- RegisterThreadedTest::nth(current_)->fuzzer_->gate_->Signal();
+ RegisterThreadedTest::nth(current_)->fuzzer_->gate_.Signal();
return true;
}
void ApiTestFuzzer::Run() {
// When it is our turn...
- gate_->Wait();
+ gate_.Wait();
{
// ... get the V8 lock and start running the test.
v8::Locker locker(CcTest::default_isolate());
@@ -12287,7 +12295,7 @@
active_tests_--;
// If it was the last then signal that fact.
if (active_tests_ == 0) {
- all_tests_done_->Signal();
+ all_tests_done_.Signal();
} else {
// Otherwise select a new test and start that.
NextThread();
@@ -12324,7 +12332,7 @@
current_ = -1;
NextThread();
// Wait till they are all done.
- all_tests_done_->Wait();
+ all_tests_done_.Wait();
}
@@ -12345,7 +12353,7 @@
// Now it can start.
v8::Unlocker unlocker(CcTest::default_isolate());
// Wait till someone starts us again.
- gate_->Wait();
+ gate_.Wait();
// And we're off.
}
}
@@ -12599,7 +12607,7 @@
void*) {
v8::HandleScope scope(isolate);
bad_handle.Reset(isolate, some_object);
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -12619,7 +12627,7 @@
// in reverse allocation order, so if second allocated handle is deleted,
// weak callback of the first handle would be able to 'reallocate' it.
handle1.MakeWeak<v8::Value, void>(NULL, NewPersistentHandleCallback);
- handle2.Dispose(isolate);
+ handle2.Dispose();
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -12629,9 +12637,9 @@
void DisposeAndForceGcCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
- to_be_disposed.Dispose(isolate);
+ to_be_disposed.Dispose();
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -12653,7 +12661,7 @@
void DisposingCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
- handle->Dispose(isolate);
+ handle->Dispose();
}
void HandleCreatingCallback(v8::Isolate* isolate,
@@ -12661,7 +12669,7 @@
void*) {
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object>(isolate, v8::Object::New());
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -14061,10 +14069,9 @@
class RegExpInterruptTest {
public:
- RegExpInterruptTest() : block_(NULL) {}
- ~RegExpInterruptTest() { delete block_; }
+ RegExpInterruptTest() : block_(0) {}
+ ~RegExpInterruptTest() {}
void RunTest() {
- block_ = i::OS::CreateSemaphore(0);
gc_count_ = 0;
gc_during_regexp_ = 0;
regexp_success_ = false;
@@ -14099,7 +14106,7 @@
};
void CollectGarbage() {
- block_->Wait();
+ block_.Wait();
while (gc_during_regexp_ < kRequiredGCs) {
{
v8::Locker lock(CcTest::default_isolate());
@@ -14113,7 +14120,7 @@
}
void LongRunningRegExp() {
- block_->Signal(); // Enable garbage collection thread on next preemption.
+ block_.Signal(); // Enable garbage collection thread on next preemption.
int rounds = 0;
while (gc_during_regexp_ < kRequiredGCs) {
int gc_before = gc_count_;
@@ -14151,7 +14158,7 @@
regexp_success_ = true;
}
- i::Semaphore* block_;
+ i::Semaphore block_;
int gc_count_;
int gc_during_regexp_;
bool regexp_success_;
@@ -14184,10 +14191,9 @@
class ApplyInterruptTest {
public:
- ApplyInterruptTest() : block_(NULL) {}
- ~ApplyInterruptTest() { delete block_; }
+ ApplyInterruptTest() : block_(0) {}
+ ~ApplyInterruptTest() {}
void RunTest() {
- block_ = i::OS::CreateSemaphore(0);
gc_count_ = 0;
gc_during_apply_ = 0;
apply_success_ = false;
@@ -14222,7 +14228,7 @@
};
void CollectGarbage() {
- block_->Wait();
+ block_.Wait();
while (gc_during_apply_ < kRequiredGCs) {
{
v8::Locker lock(CcTest::default_isolate());
@@ -14235,7 +14241,7 @@
}
void LongRunningApply() {
- block_->Signal();
+ block_.Signal();
int rounds = 0;
while (gc_during_apply_ < kRequiredGCs) {
int gc_before = gc_count_;
@@ -14260,7 +14266,7 @@
apply_success_ = true;
}
- i::Semaphore* block_;
+ i::Semaphore block_;
int gc_count_;
int gc_during_apply_;
bool apply_success_;
@@ -14473,12 +14479,12 @@
class RegExpStringModificationTest {
public:
RegExpStringModificationTest()
- : block_(i::OS::CreateSemaphore(0)),
+ : block_(0),
morphs_(0),
morphs_during_regexp_(0),
ascii_resource_(i::Vector<const char>("aaaaaaaaaaaaaab", 15)),
uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {}
- ~RegExpStringModificationTest() { delete block_; }
+ ~RegExpStringModificationTest() {}
void RunTest() {
i::Factory* factory = i::Isolate::Current()->factory();
@@ -14535,7 +14541,7 @@
};
void MorphString() {
- block_->Wait();
+ block_.Wait();
while (morphs_during_regexp_ < kRequiredModifications &&
morphs_ < kMaxModifications) {
{
@@ -14551,7 +14557,7 @@
}
void LongRunningRegExp() {
- block_->Signal(); // Enable morphing thread on next preemption.
+ block_.Signal(); // Enable morphing thread on next preemption.
while (morphs_during_regexp_ < kRequiredModifications &&
morphs_ < kMaxModifications) {
int morphs_before = morphs_;
@@ -14573,7 +14579,7 @@
}
i::uc16 two_byte_content_[15];
- i::Semaphore* block_;
+ i::Semaphore block_;
int morphs_;
int morphs_during_regexp_;
bool regexp_success_;
@@ -18593,15 +18599,15 @@
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object> object(isolate, v8::Object::New());
- CHECK_EQ(0, object.WrapperClassId(isolate));
- object.SetWrapperClassId(isolate, 42);
- CHECK_EQ(42, object.WrapperClassId(isolate));
+ CHECK_EQ(0, object.WrapperClassId());
+ object.SetWrapperClassId(42);
+ CHECK_EQ(42, object.WrapperClassId());
Visitor42 visitor(&object);
v8::V8::VisitHandlesWithClassIds(&visitor);
CHECK_EQ(1, visitor.counter_);
- object.Dispose(isolate);
+ object.Dispose();
}
@@ -18610,10 +18616,10 @@
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object> object(isolate, v8::Object::New());
- CHECK_EQ(0, object.WrapperClassId(isolate));
- object.SetWrapperClassId(isolate, 65535);
- CHECK_EQ(65535, object.WrapperClassId(isolate));
- object.Dispose(isolate);
+ CHECK_EQ(0, object.WrapperClassId());
+ object.SetWrapperClassId(65535);
+ CHECK_EQ(65535, object.WrapperClassId());
+ object.Dispose();
}
@@ -18622,23 +18628,23 @@
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
v8::Persistent<v8::Object> object1(isolate, v8::Object::New());
- CHECK_EQ(0, object1.WrapperClassId(isolate));
- object1.SetWrapperClassId(isolate, 42);
- CHECK_EQ(42, object1.WrapperClassId(isolate));
+ CHECK_EQ(0, object1.WrapperClassId());
+ object1.SetWrapperClassId(42);
+ CHECK_EQ(42, object1.WrapperClassId());
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
v8::Persistent<v8::Object> object2(isolate, v8::Object::New());
- CHECK_EQ(0, object2.WrapperClassId(isolate));
- object2.SetWrapperClassId(isolate, 42);
- CHECK_EQ(42, object2.WrapperClassId(isolate));
+ CHECK_EQ(0, object2.WrapperClassId());
+ object2.SetWrapperClassId(42);
+ CHECK_EQ(42, object2.WrapperClassId());
Visitor42 visitor(&object2);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
CHECK_EQ(1, visitor.counter_);
- object1.Dispose(isolate);
- object2.Dispose(isolate);
+ object1.Dispose();
+ object2.Dispose();
}
@@ -20070,16 +20076,14 @@
#if V8_OS_POSIX
class ThreadInterruptTest {
public:
- ThreadInterruptTest() : sem_(NULL), sem_value_(0) { }
- ~ThreadInterruptTest() { delete sem_; }
+ ThreadInterruptTest() : sem_(0), sem_value_(0) { }
+ ~ThreadInterruptTest() {}
void RunTest() {
- sem_ = i::OS::CreateSemaphore(0);
-
InterruptThread i_thread(this);
i_thread.Start();
- sem_->Wait();
+ sem_.Wait();
CHECK_EQ(kExpectedValue, sem_value_);
}
@@ -20110,7 +20114,7 @@
// Set value and signal semaphore
test_->sem_value_ = 1;
- test_->sem_->Signal();
+ test_->sem_.Signal();
}
static void SignalHandler(int signal) {
@@ -20120,7 +20124,7 @@
ThreadInterruptTest* test_;
};
- i::Semaphore* sem_;
+ i::Semaphore sem_;
volatile int sem_value_;
};
@@ -20309,4 +20313,109 @@
v8::V8::SetFailedAccessCheckCallbackFunction(NULL);
}
+
+THREADED_TEST(Regress256330) {
+ i::FLAG_allow_natives_syntax = true;
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ context->Global()->Set(v8_str("Bug"), templ->GetFunction());
+ CompileRun("\"use strict\"; var o = new Bug;"
+ "function f(o) { o.x = 10; };"
+ "f(o); f(o); f(o);"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f(o);");
+ ExpectBoolean("%GetOptimizationStatus(f) != 2", true);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorSetter) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ // Initialize fields to avoid transitions later.
+ "obj.age = 0;"
+ "obj.accessor_age = 42;"
+ "function setter(i) { this.accessor_age = i; };"
+ "function getter() { return this.accessor_age; };"
+ "function setAge(i) { obj.age = i; };"
+ "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
+ "setAge(1);"
+ "setAge(2);"
+ "setAge(3);"
+ "%OptimizeFunctionOnNextCall(setAge);"
+ "setAge(4);");
+ // All stores went through the interceptor.
+ ExpectInt32("obj.interceptor_age", 4);
+ ExpectInt32("obj.accessor_age", 42);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorGetter) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ // Initialize fields to avoid transitions later.
+ "obj.age = 1;"
+ "obj.accessor_age = 42;"
+ "function getter() { return this.accessor_age; };"
+ "function getAge() { return obj.interceptor_age; };"
+ "Object.defineProperty(obj, 'interceptor_age', { get:getter });"
+ "getAge();"
+ "getAge();"
+ "getAge();"
+ "%OptimizeFunctionOnNextCall(getAge);");
+ // Access through interceptor.
+ ExpectInt32("getAge()", 1);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorFieldRead) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "obj.__proto__.interceptor_age = 42;"
+ "obj.age = 100;"
+ "function getAge() { return obj.interceptor_age; };");
+ ExpectInt32("getAge();", 100);
+ ExpectInt32("getAge();", 100);
+ ExpectInt32("getAge();", 100);
+ CompileRun("%OptimizeFunctionOnNextCall(getAge);");
+ // Access through interceptor.
+ ExpectInt32("getAge();", 100);
+}
+
+
+THREADED_TEST(CrankshaftInterceptorFieldWrite) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "obj.age = 100000;"
+ "function setAge(i) { obj.age = i };"
+ "setAge(100);"
+ "setAge(101);"
+ "setAge(102);"
+ "%OptimizeFunctionOnNextCall(setAge);"
+ "setAge(103);");
+ ExpectInt32("obj.age", 100000);
+ ExpectInt32("obj.interceptor_age", 103);
+}
+
#endif // V8_OS_POSIX
diff --git a/test/cctest/test-circular-queue.cc b/test/cctest/test-circular-queue.cc
index 7b21d1e..1d6775d 100644
--- a/test/cctest/test-circular-queue.cc
+++ b/test/cctest/test-circular-queue.cc
@@ -142,15 +142,15 @@
const int kRecordsPerChunk = 4;
TestSampleQueue scq;
- i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
+ i::Semaphore semaphore(0);
- ProducerThread producer1(&scq, kRecordsPerChunk, 1, semaphore);
- ProducerThread producer2(&scq, kRecordsPerChunk, 10, semaphore);
- ProducerThread producer3(&scq, kRecordsPerChunk, 20, semaphore);
+ ProducerThread producer1(&scq, kRecordsPerChunk, 1, &semaphore);
+ ProducerThread producer2(&scq, kRecordsPerChunk, 10, &semaphore);
+ ProducerThread producer3(&scq, kRecordsPerChunk, 20, &semaphore);
CHECK_EQ(NULL, scq.StartDequeue());
producer1.Start();
- semaphore->Wait();
+ semaphore.Wait();
for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) {
Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
CHECK_NE(NULL, rec);
@@ -162,7 +162,7 @@
CHECK_EQ(NULL, scq.StartDequeue());
producer2.Start();
- semaphore->Wait();
+ semaphore.Wait();
for (Record i = 10; i < 10 + kRecordsPerChunk; ++i) {
Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
CHECK_NE(NULL, rec);
@@ -174,7 +174,7 @@
CHECK_EQ(NULL, scq.StartDequeue());
producer3.Start();
- semaphore->Wait();
+ semaphore.Wait();
for (Record i = 20; i < 20 + kRecordsPerChunk; ++i) {
Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
CHECK_NE(NULL, rec);
@@ -185,6 +185,4 @@
}
CHECK_EQ(NULL, scq.StartDequeue());
-
- delete semaphore;
}
diff --git a/test/cctest/test-condition-variable.cc b/test/cctest/test-condition-variable.cc
new file mode 100644
index 0000000..774983e
--- /dev/null
+++ b/test/cctest/test-condition-variable.cc
@@ -0,0 +1,162 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "platform/condition-variable.h"
+#include "platform/time.h"
+
+using namespace ::v8::internal;
+
+
+TEST(WaitForAfterNofityOnSameThread) {
+ for (int n = 0; n < 10; ++n) {
+ Mutex mutex;
+ ConditionVariable cv;
+
+ LockGuard<Mutex> lock_guard(&mutex);
+
+ cv.NotifyOne();
+ CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+
+ cv.NotifyAll();
+ CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
+ }
+}
+
+
+class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread {
+ public:
+ ThreadWithMutexAndConditionVariable()
+ : Thread("ThreadWithMutexAndConditionVariable"),
+ running_(false), finished_(false) {}
+ virtual ~ThreadWithMutexAndConditionVariable() {}
+
+ virtual void Run() V8_OVERRIDE {
+ LockGuard<Mutex> lock_guard(&mutex_);
+ running_ = true;
+ cv_.NotifyOne();
+ cv_.Wait(&mutex_);
+ running_ = false;
+ finished_ = true;
+ cv_.NotifyOne();
+ }
+
+ volatile bool running_;
+ volatile bool finished_;
+ ConditionVariable cv_;
+ Mutex mutex_;
+};
+
+
+TEST(MultipleThreadsWithSeparateConditionVariables) {
+ static const int kThreadCount = 16;
+ static const TimeDelta kMaxThreadStartTime =
+ TimeDelta::FromMilliseconds(250) * kThreadCount;
+ ThreadWithMutexAndConditionVariable threads[kThreadCount];
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(!threads[n].running_);
+ CHECK(!threads[n].finished_);
+ threads[n].Start();
+ // Wait for nth thread to start.
+ CHECK(threads[n].cv_.WaitFor(&threads[n].mutex_, kMaxThreadStartTime));
+ }
+
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(threads[n].running_);
+ CHECK(!threads[n].finished_);
+ }
+
+ for (int n = 0; n < kThreadCount; ++n) {
+ threads[n].cv_.NotifyOne();
+ }
+
+ for (int n = kThreadCount - 1; n >= 0; --n) {
+ // Wait for nth thread to quit.
+ threads[n].Join();
+ LockGuard<Mutex> lock_guard(&threads[n].mutex_);
+ CHECK(!threads[n].running_);
+ CHECK(threads[n].finished_);
+ }
+}
+
+
+static int loop_counter = 0;
+static const int kLoopCounterLimit = 100;
+
+class LoopIncrementThread V8_FINAL : public Thread {
+ public:
+ LoopIncrementThread(const char* name,
+ int rem,
+ ConditionVariable* cv,
+ Mutex* mutex)
+ : Thread(name), rem_(rem), cv_(cv), mutex_(mutex) {}
+ virtual ~LoopIncrementThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ int last_count = -1;
+ while (true) {
+ LockGuard<Mutex> lock_guard(mutex_);
+ int count = loop_counter;
+ while (count % 2 != rem_ && count < kLoopCounterLimit) {
+ cv_->Wait(mutex_);
+ count = loop_counter;
+ }
+ if (count >= kLoopCounterLimit) break;
+ CHECK_EQ(loop_counter, count);
+ if (last_count != -1) {
+ CHECK_EQ(last_count + 1, count);
+ }
+ count++;
+ loop_counter = count;
+ last_count = count;
+ cv_->NotifyOne();
+ }
+ }
+
+ private:
+ const int rem_;
+ ConditionVariable* cv_;
+ Mutex* mutex_;
+};
+
+
+TEST(LoopIncrement) {
+ Mutex mutex;
+ ConditionVariable cv;
+ LoopIncrementThread t0("t0", 0, &cv, &mutex);
+ LoopIncrementThread t1("t1", 1, &cv, &mutex);
+ t0.Start();
+ t1.Start();
+ t0.Join();
+ t1.Join();
+ CHECK_EQ(kLoopCounterLimit, loop_counter);
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index c12cb58..b41a77a 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -4197,7 +4197,8 @@
{
v8::Debug::DebugBreak();
- v8::internal::DisableBreak disable_break(true);
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
+ v8::internal::DisableBreak disable_break(isolate, true);
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
}
@@ -4679,13 +4680,12 @@
int num_threads_;
int num_blocked_;
v8::internal::Mutex lock_;
- v8::internal::Semaphore* sem_;
+ v8::internal::Semaphore sem_;
bool invalid_;
};
ThreadBarrier::ThreadBarrier(int num_threads)
- : num_threads_(num_threads), num_blocked_(0) {
- sem_ = OS::CreateSemaphore(0);
+ : num_threads_(num_threads), num_blocked_(0), sem_(0) {
invalid_ = false; // A barrier may only be used once. Then it is invalid.
}
@@ -4693,7 +4693,6 @@
// Do not call, due to race condition with Wait().
// Could be resolved with Pthread condition variables.
ThreadBarrier::~ThreadBarrier() {
- delete sem_;
}
@@ -4703,7 +4702,7 @@
if (num_blocked_ == num_threads_ - 1) {
// Signal and unblock all waiting threads.
for (int i = 0; i < num_threads_ - 1; ++i) {
- sem_->Signal();
+ sem_.Signal();
}
invalid_ = true;
printf("BARRIER\n\n");
@@ -4712,7 +4711,7 @@
} else { // Wait for the semaphore.
++num_blocked_;
lock_.Unlock(); // Potential race condition with destructor because
- sem_->Wait(); // these two lines are not atomic.
+ sem_.Wait(); // these two lines are not atomic.
}
}
@@ -4735,8 +4734,8 @@
barrier_3(2), barrier_4(2), barrier_5(2) {}
void Barriers::Initialize() {
- semaphore_1 = OS::CreateSemaphore(0);
- semaphore_2 = OS::CreateSemaphore(0);
+ semaphore_1 = new v8::internal::Semaphore(0);
+ semaphore_2 = new v8::internal::Semaphore(0);
}
@@ -5990,17 +5989,16 @@
port_(port),
server_(NULL),
client_(NULL),
- listening_(OS::CreateSemaphore(0)) {
+ listening_(0) {
}
~DebuggerAgentProtocolServerThread() {
// Close both sockets.
delete client_;
delete server_;
- delete listening_;
}
void Run();
- void WaitForListening() { listening_->Wait(); }
+ void WaitForListening() { listening_.Wait(); }
char* body() { return *body_; }
private:
@@ -6008,7 +6006,7 @@
i::SmartArrayPointer<char> body_;
i::Socket* server_; // Server socket used for bind/accept.
i::Socket* client_; // Single client connection used by the test.
- i::Semaphore* listening_; // Signalled when the server is in listen mode.
+ i::Semaphore listening_; // Signalled when the server is in listen mode.
};
@@ -6024,7 +6022,7 @@
// Listen for new connections.
ok = server_->Listen(1);
CHECK(ok);
- listening_->Signal();
+ listening_.Signal();
// Accept a connection.
client_ = server_->Accept();
@@ -6637,7 +6635,7 @@
v8::Local<v8::Context>::New(isolate, context);
local_context->Exit();
}
- context.Dispose(isolate);
+ context.Dispose();
// Do garbage collection to collect the script above which is no longer
// referenced.
diff --git a/test/cctest/test-declarative-accessors.cc b/test/cctest/test-declarative-accessors.cc
index 2d2f5cd..e3c7fa5 100644
--- a/test/cctest/test-declarative-accessors.cc
+++ b/test/cctest/test-declarative-accessors.cc
@@ -38,11 +38,11 @@
public:
static const unsigned kArraySize = 200;
explicit HandleArray() {}
- ~HandleArray() { Reset(v8::Isolate::GetCurrent()); }
- void Reset(v8::Isolate* isolate) {
+ ~HandleArray() { Reset(); }
+ void Reset() {
for (unsigned i = 0; i < kArraySize; i++) {
if (handles_[i].IsEmpty()) continue;
- handles_[i].Dispose(isolate);
+ handles_[i].Dispose();
handles_[i].Clear();
}
}
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index 0f6bb8f..18f1420 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -56,7 +56,7 @@
HandleScope scope(isolate);
Local<Context> context = Local<Context>::New(isolate, context_);
context->Exit();
- context_.Dispose(isolate);
+ context_.Dispose();
}
}
diff --git a/test/cctest/test-deoptimization.cc b/test/cctest/test-deoptimization.cc
index 10fe99c..83a6354 100644
--- a/test/cctest/test-deoptimization.cc
+++ b/test/cctest/test-deoptimization.cc
@@ -367,7 +367,7 @@
i::FLAG_always_opt = true;
CompileRun(f_source);
CompileRun("f('a+', new X());");
- CHECK(!i::V8::UseCrankshaft() ||
+ CHECK(!i::Isolate::Current()->use_crankshaft() ||
GetJSFunction(env->Global(), "f")->IsOptimized());
// Call f and force deoptimization while processing the binary operation.
@@ -419,7 +419,7 @@
i::FLAG_always_opt = true;
CompileRun(f_source);
CompileRun("f(7, new X());");
- CHECK(!i::V8::UseCrankshaft() ||
+ CHECK(!i::Isolate::Current()->use_crankshaft() ||
GetJSFunction((*env)->Global(), "f")->IsOptimized());
// Call f and force deoptimization while processing the binary operation.
@@ -517,7 +517,7 @@
i::FLAG_always_opt = true;
CompileRun(f_source);
CompileRun("f('a', new X());");
- CHECK(!i::V8::UseCrankshaft() ||
+ CHECK(!i::Isolate::Current()->use_crankshaft() ||
GetJSFunction(env->Global(), "f")->IsOptimized());
// Call f and force deoptimization while processing the comparison.
@@ -587,7 +587,7 @@
CompileRun("g1(new X());");
CompileRun("f2(new X(), 'z');");
CompileRun("g2(new X(), 'z');");
- if (i::V8::UseCrankshaft()) {
+ if (i::Isolate::Current()->use_crankshaft()) {
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
@@ -671,7 +671,7 @@
CompileRun("g1(new X());");
CompileRun("f2(new X(), 'z');");
CompileRun("g2(new X(), 'z');");
- if (i::V8::UseCrankshaft()) {
+ if (i::Isolate::Current()->use_crankshaft()) {
CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized());
CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized());
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index e30fcc0..04f6e0f 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -1201,11 +1201,11 @@
heap_profiler->SetWrapperClassInfoProvider(
2, TestRetainedObjectInfo::WrapperInfoCallback);
v8::Persistent<v8::String> p_AAA(isolate, v8_str("AAA"));
- p_AAA.SetWrapperClassId(isolate, 1);
+ p_AAA.SetWrapperClassId(1);
v8::Persistent<v8::String> p_BBB(isolate, v8_str("BBB"));
- p_BBB.SetWrapperClassId(isolate, 1);
+ p_BBB.SetWrapperClassId(1);
v8::Persistent<v8::String> p_CCC(isolate, v8_str("CCC"));
- p_CCC.SetWrapperClassId(isolate, 2);
+ p_CCC.SetWrapperClassId(2);
CHECK_EQ(0, TestRetainedObjectInfo::instances.length());
const v8::HeapSnapshot* snapshot =
heap_profiler->TakeHeapSnapshot(v8_str("retained"));
@@ -1711,7 +1711,7 @@
static void PersistentHandleCallback(v8::Isolate* isolate,
v8::Persistent<v8::Value>* handle,
void*) {
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index fc6a1ec..611e6e3 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -82,16 +82,18 @@
static void CheckOddball(Isolate* isolate, Object* obj, const char* string) {
CHECK(obj->IsOddball());
bool exc;
+ Handle<Object> handle(obj, isolate);
Object* print_string =
- *Execution::ToString(Handle<Object>(obj, isolate), &exc);
+ *Execution::ToString(isolate, handle, &exc);
CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string)));
}
static void CheckSmi(Isolate* isolate, int value, const char* string) {
bool exc;
+ Handle<Object> handle(Smi::FromInt(value), isolate);
Object* print_string =
- *Execution::ToString(Handle<Object>(Smi::FromInt(value), isolate), &exc);
+ *Execution::ToString(isolate, handle, &exc);
CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string)));
}
@@ -100,8 +102,9 @@
Object* obj = HEAP->NumberFromDouble(value)->ToObjectChecked();
CHECK(obj->IsNumber());
bool exc;
+ Handle<Object> handle(obj, isolate);
Object* print_string =
- *Execution::ToString(Handle<Object>(obj, isolate), &exc);
+ *Execution::ToString(isolate, handle, &exc);
CHECK(String::cast(print_string)->IsUtf8EqualTo(CStrVector(string)));
}
@@ -398,7 +401,7 @@
v8::Persistent<v8::Value>* handle,
void* id) {
if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true;
- handle->Dispose(isolate);
+ handle->Dispose();
}
@@ -1332,7 +1335,7 @@
isolate->compilation_cache()->Clear();
heap->CollectAllGarbage(Heap::kNoGCFlags);
- bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
+ bool opt = (FLAG_always_opt && isolate->use_crankshaft());
CHECK_EQ(i + 1, CountNativeContexts());
@@ -1476,7 +1479,7 @@
CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1));
}
- bool opt = (FLAG_always_opt && i::V8::UseCrankshaft());
+ bool opt = (FLAG_always_opt && isolate->use_crankshaft());
// Compile a number of functions the length of the weak list of optimized
// functions both with and without GCs while iterating the list.
@@ -1720,12 +1723,12 @@
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
- ctx1p.Dispose(isolate);
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1766,12 +1769,12 @@
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
- ctx1p.Dispose(ctx1->GetIsolate());
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1810,12 +1813,12 @@
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
- ctx1p.Dispose(ctx1->GetIsolate());
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1858,12 +1861,12 @@
ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
ctx2->Exit();
ctx1->Exit();
- ctx1p.Dispose(isolate);
+ ctx1p.Dispose();
v8::V8::ContextDisposedNotification();
}
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(2, NumberOfGlobalObjects());
- ctx2p.Dispose(isolate);
+ ctx2p.Dispose();
HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, NumberOfGlobalObjects());
}
@@ -1876,7 +1879,7 @@
#endif
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft()) return;
+ if (!i::Isolate::Current()->use_crankshaft()) return;
if (i::FLAG_force_marking_deque_overflows) return;
v8::HandleScope outer_scope(v8::Isolate::GetCurrent());
@@ -1993,7 +1996,7 @@
#endif
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft()) return;
+ if (!i::Isolate::Current()->use_crankshaft()) return;
v8::HandleScope outer_scope(v8::Isolate::GetCurrent());
{
@@ -2050,7 +2053,7 @@
#endif
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft()) return;
+ if (!i::Isolate::Current()->use_crankshaft()) return;
v8::HandleScope outer_scope(CcTest::isolate());
{
@@ -2089,7 +2092,7 @@
TEST(OptimizedAllocationAlwaysInNewSpace) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
@@ -2118,7 +2121,7 @@
TEST(OptimizedPretenuringAllocationFolding) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2154,7 +2157,7 @@
TEST(OptimizedPretenuringAllocationFoldingBlocks) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2190,7 +2193,7 @@
TEST(OptimizedPretenuringObjectArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2215,7 +2218,7 @@
TEST(OptimizedPretenuringMixedInObjectProperties) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2246,7 +2249,7 @@
TEST(OptimizedPretenuringDoubleArrayProperties) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2271,7 +2274,7 @@
TEST(OptimizedPretenuringdoubleArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2296,7 +2299,7 @@
TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2330,7 +2333,7 @@
TEST(OptimizedPretenuringNestedObjectLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2364,7 +2367,7 @@
TEST(OptimizedPretenuringNestedDoubleLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
@@ -2401,7 +2404,7 @@
TEST(OptimizedAllocationArrayLiterals) {
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
@@ -2428,7 +2431,7 @@
i::FLAG_allow_natives_syntax = true;
i::FLAG_pretenuring_call_new = true;
CcTest::InitializeVM();
- if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+ if (!i::Isolate::Current()->use_crankshaft() || i::FLAG_always_opt) return;
if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
v8::HandleScope scope(CcTest::isolate());
HEAP->SetNewSpaceHighPromotionModeActive(true);
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index 90e1f75..a143d58 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -129,20 +129,18 @@
public:
explicit JoinableThread(const char* name)
: name_(name),
- semaphore_(i::OS::CreateSemaphore(0)),
+ semaphore_(0),
thread_(this) {
}
- virtual ~JoinableThread() {
- delete semaphore_;
- }
+ virtual ~JoinableThread() {}
void Start() {
thread_.Start();
}
void Join() {
- semaphore_->Wait();
+ semaphore_.Wait();
}
virtual void Run() = 0;
@@ -157,7 +155,7 @@
virtual void Run() {
joinable_thread_->Run();
- joinable_thread_->semaphore_->Signal();
+ joinable_thread_->semaphore_.Signal();
}
private:
@@ -165,7 +163,7 @@
};
const char* name_;
- i::Semaphore* semaphore_;
+ i::Semaphore semaphore_;
ThreadWithSemaphore thread_;
friend class ThreadWithSemaphore;
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index 6bf56f0..f752c36 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -127,7 +127,7 @@
public:
explicit LoopingThread(v8::internal::Isolate* isolate)
: v8::internal::Thread(isolate),
- semaphore_(v8::internal::OS::CreateSemaphore(0)),
+ semaphore_(new v8::internal::Semaphore(0)),
run_(true) {
}
@@ -213,7 +213,7 @@
public:
explicit TestSampler(v8::internal::Isolate* isolate)
: Sampler(isolate, 0, true, true),
- semaphore_(v8::internal::OS::CreateSemaphore(0)),
+ semaphore_(new v8::internal::Semaphore(0)),
was_sample_stack_called_(false) {
}
@@ -427,9 +427,6 @@
// it launches a new cctest instance for every test. To be sure that launching
// cctest manually also works, please be sure that no tests below
// are using V8.
- //
- // P.S. No, V8 can't be re-initialized after disposal, see include/v8.h.
- CHECK(!i::V8::IsRunning());
// Start with profiling to capture all code events from the beginning.
ScopedLoggerInitializer initialize_logger;
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index c239752..21700f7 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -307,7 +307,7 @@
void* id) {
ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/test/cctest/test-platform-linux.cc b/test/cctest/test-platform-linux.cc
index 7347aac..34ae43c 100644
--- a/test/cctest/test-platform-linux.cc
+++ b/test/cctest/test-platform-linux.cc
@@ -39,55 +39,6 @@
using namespace ::v8::internal;
-static void yield() {
- usleep(1);
-}
-
-static const int kLockCounterLimit = 50;
-static int busy_lock_counter = 0;
-
-
-static void LoopIncrement(Mutex* mutex, int rem) {
- while (true) {
- int count = 0;
- int last_count = -1;
- do {
- LockGuard<Mutex> lock_guard(mutex);
- count = busy_lock_counter;
- yield();
- } while (count % 2 == rem && count < kLockCounterLimit);
- if (count >= kLockCounterLimit) break;
- LockGuard<Mutex> lock_guard(mutex);
- CHECK_EQ(count, busy_lock_counter);
- CHECK(last_count == -1 || count == last_count + 1);
- busy_lock_counter++;
- last_count = count;
- yield();
- }
-}
-
-
-static void* RunTestBusyLock(void* arg) {
- LoopIncrement(static_cast<Mutex*>(arg), 0);
- return 0;
-}
-
-
-// Runs two threads that repeatedly acquire the lock and conditionally
-// increment a variable.
-TEST(BusyLock) {
- pthread_t other;
- Mutex mutex;
- int thread_created = pthread_create(&other,
- NULL,
- &RunTestBusyLock,
- &mutex);
- CHECK_EQ(0, thread_created);
- LoopIncrement(&mutex, 1);
- pthread_join(other, NULL);
-}
-
-
TEST(VirtualMemory) {
OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
diff --git a/test/cctest/test-random.cc b/test/cctest/test-random.cc
index 0a8594c..2f7ab7d 100644
--- a/test/cctest/test-random.cc
+++ b/test/cctest/test-random.cc
@@ -69,7 +69,7 @@
TEST(CrankshaftRandom) {
v8::V8::Initialize();
// Skip test if crankshaft is disabled.
- if (!V8::UseCrankshaft()) return;
+ if (!Isolate::Current()->use_crankshaft()) return;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
v8::Context::Scope context_scope(v8::Context::New(isolate));
diff --git a/test/cctest/test-semaphore.cc b/test/cctest/test-semaphore.cc
new file mode 100644
index 0000000..895303f
--- /dev/null
+++ b/test/cctest/test-semaphore.cc
@@ -0,0 +1,155 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "platform.h"
+#include "cctest.h"
+
+
+using namespace ::v8::internal;
+
+
+class WaitAndSignalThread V8_FINAL : public Thread {
+ public:
+ explicit WaitAndSignalThread(Semaphore* semaphore)
+ : Thread("WaitAndSignalThread"), semaphore_(semaphore) {}
+ virtual ~WaitAndSignalThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ for (int n = 0; n < 1000; ++n) {
+ semaphore_->Wait();
+ bool result = semaphore_->WaitFor(TimeDelta::FromMicroseconds(1));
+ ASSERT(!result);
+ USE(result);
+ semaphore_->Signal();
+ }
+ }
+
+ private:
+ Semaphore* semaphore_;
+};
+
+
+TEST(WaitAndSignal) {
+ Semaphore semaphore(0);
+ WaitAndSignalThread t1(&semaphore);
+ WaitAndSignalThread t2(&semaphore);
+
+ t1.Start();
+ t2.Start();
+
+ // Make something available.
+ semaphore.Signal();
+
+ t1.Join();
+ t2.Join();
+
+ semaphore.Wait();
+
+ bool result = semaphore.WaitFor(TimeDelta::FromMicroseconds(1));
+ ASSERT(!result);
+ USE(result);
+}
+
+
+TEST(WaitFor) {
+ bool ok;
+ Semaphore semaphore(0);
+
+ // Semaphore not signalled - timeout.
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
+ CHECK(!ok);
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
+ CHECK(!ok);
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
+ CHECK(!ok);
+
+ // Semaphore signalled - no timeout.
+ semaphore.Signal();
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
+ CHECK(ok);
+ semaphore.Signal();
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
+ CHECK(ok);
+ semaphore.Signal();
+ ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
+ CHECK(ok);
+}
+
+
+static const char alphabet[] = "XKOAD";
+static const int kAlphabetSize = sizeof(alphabet) - 1;
+static const int kBufferSize = 4096; // GCD(buffer size, alphabet size) = 1
+static char buffer[kBufferSize];
+static const int kDataSize = kBufferSize * kAlphabetSize * 10;
+
+static Semaphore free_space(kBufferSize);
+static Semaphore used_space(0);
+
+
+class ProducerThread V8_FINAL : public Thread {
+ public:
+ ProducerThread() : Thread("ProducerThread") {}
+ virtual ~ProducerThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ for (int n = 0; n < kDataSize; ++n) {
+ free_space.Wait();
+ buffer[n % kBufferSize] = alphabet[n % kAlphabetSize];
+ used_space.Signal();
+ }
+ }
+};
+
+
+class ConsumerThread V8_FINAL : public Thread {
+ public:
+ ConsumerThread() : Thread("ConsumerThread") {}
+ virtual ~ConsumerThread() {}
+
+ virtual void Run() V8_OVERRIDE {
+ for (int n = 0; n < kDataSize; ++n) {
+ used_space.Wait();
+ ASSERT_EQ(static_cast<int>(alphabet[n % kAlphabetSize]),
+ static_cast<int>(buffer[n % kBufferSize]));
+ free_space.Signal();
+ }
+ }
+};
+
+
+TEST(ProducerConsumer) {
+ ProducerThread producer_thread;
+ ConsumerThread consumer_thread;
+ producer_thread.Start();
+ consumer_thread.Start();
+ producer_thread.Join();
+ consumer_thread.Join();
+}
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index f95ff65..bd0bca7 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -412,7 +412,7 @@
v8::HandleScope handle_scope(v8_isolate);
v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
}
- env.Dispose(v8_isolate);
+ env.Dispose();
FileByteSink startup_sink(startup_name.start());
StartupSerializer startup_serializer(&startup_sink);
@@ -558,7 +558,7 @@
i::Object* raw_context = *v8::Utils::OpenPersistent(env);
- env.Dispose(v8_isolate);
+ env.Dispose();
FileByteSink startup_sink(startup_name.start());
StartupSerializer startup_serializer(&startup_sink);
diff --git a/test/cctest/test-sockets.cc b/test/cctest/test-sockets.cc
index a9e31fc..87a62ce 100644
--- a/test/cctest/test-sockets.cc
+++ b/test/cctest/test-sockets.cc
@@ -41,19 +41,18 @@
data_size_(data_size),
server_(NULL),
client_(NULL),
- listening_(OS::CreateSemaphore(0)) {
+ listening_(0) {
data_ = new char[data_size_];
}
~SocketListenerThread() {
// Close both sockets.
delete client_;
delete server_;
- delete listening_;
delete[] data_;
}
void Run();
- void WaitForListening() { listening_->Wait(); }
+ void WaitForListening() { listening_.Wait(); }
char* data() { return data_; }
private:
@@ -62,7 +61,7 @@
int data_size_;
Socket* server_; // Server socket used for bind/accept.
Socket* client_; // Single client connection used by the test.
- Semaphore* listening_; // Signalled when the server socket is in listen mode.
+ Semaphore listening_; // Signalled when the server socket is in listen mode.
};
@@ -79,7 +78,7 @@
// Listen for new connections.
ok = server_->Listen(1);
CHECK(ok);
- listening_->Signal();
+ listening_.Signal();
// Accept a connection.
client_ = server_->Accept();
diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc
index b29b1dc..4c08539 100644
--- a/test/cctest/test-thread-termination.cc
+++ b/test/cctest/test-thread-termination.cc
@@ -171,7 +171,7 @@
// Test that a single thread of JavaScript execution can be terminated
// from the side by another thread.
TEST(TerminateOnlyV8ThreadFromOtherThread) {
- semaphore = v8::internal::OS::CreateSemaphore(0);
+ semaphore = new v8::internal::Semaphore(0);
TerminatorThread thread(i::Isolate::Current());
thread.Start();
@@ -225,7 +225,7 @@
v8::Locker locker(CcTest::default_isolate());
v8::V8::Initialize();
v8::Locker::StartPreemption(1);
- semaphore = v8::internal::OS::CreateSemaphore(0);
+ semaphore = new v8::internal::Semaphore(0);
}
const int kThreads = 2;
i::List<LoopingThread*> threads(kThreads);
diff --git a/test/cctest/test-threads.cc b/test/cctest/test-threads.cc
index a35a88d..6cc5f52 100644
--- a/test/cctest/test-threads.cc
+++ b/test/cctest/test-threads.cc
@@ -180,7 +180,7 @@
const int kNThreads = 100;
i::List<ThreadIdValidationThread*> threads(kNThreads);
i::List<i::ThreadId> refs(kNThreads);
- i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
+ i::Semaphore* semaphore = new i::Semaphore(0);
ThreadIdValidationThread* prev = NULL;
for (int i = kNThreads - 1; i >= 0; i--) {
ThreadIdValidationThread* newThread =
diff --git a/test/cctest/test-time.cc b/test/cctest/test-time.cc
index b53ee73..8b92d8d 100644
--- a/test/cctest/test-time.cc
+++ b/test/cctest/test-time.cc
@@ -56,6 +56,18 @@
}
+#if V8_OS_MACOSX
+TEST(TimeDeltaFromMachTimespec) {
+ TimeDelta null = TimeDelta();
+ CHECK(null == TimeDelta::FromMachTimespec(null.ToMachTimespec()));
+ TimeDelta delta1 = TimeDelta::FromMilliseconds(42);
+ CHECK(delta1 == TimeDelta::FromMachTimespec(delta1.ToMachTimespec()));
+ TimeDelta delta2 = TimeDelta::FromDays(42);
+ CHECK(delta2 == TimeDelta::FromMachTimespec(delta2.ToMachTimespec()));
+}
+#endif
+
+
TEST(TimeJsTime) {
Time t = Time::FromJsTime(700000.3);
CHECK_EQ(700000.3, t.ToJsTime());
@@ -63,7 +75,23 @@
#if V8_OS_POSIX
-TEST(TimeFromTimeVal) {
+TEST(TimeFromTimespec) {
+ Time null;
+ CHECK(null.IsNull());
+ CHECK(null == Time::FromTimespec(null.ToTimespec()));
+ Time now = Time::Now();
+ CHECK(now == Time::FromTimespec(now.ToTimespec()));
+ Time now_sys = Time::NowFromSystemTime();
+ CHECK(now_sys == Time::FromTimespec(now_sys.ToTimespec()));
+ Time unix_epoch = Time::UnixEpoch();
+ CHECK(unix_epoch == Time::FromTimespec(unix_epoch.ToTimespec()));
+ Time max = Time::Max();
+ CHECK(max.IsMax());
+ CHECK(max == Time::FromTimespec(max.ToTimespec()));
+}
+
+
+TEST(TimeFromTimeval) {
Time null;
CHECK(null.IsNull());
CHECK(null == Time::FromTimeval(null.ToTimeval()));
diff --git a/test/cctest/test-weakmaps.cc b/test/cctest/test-weakmaps.cc
index 9044f17..932b06b 100644
--- a/test/cctest/test-weakmaps.cc
+++ b/test/cctest/test-weakmaps.cc
@@ -69,7 +69,7 @@
void* id) {
ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/test/cctest/test-weaksets.cc b/test/cctest/test-weaksets.cc
index 707f903..aff4c7f 100644
--- a/test/cctest/test-weaksets.cc
+++ b/test/cctest/test-weaksets.cc
@@ -69,7 +69,7 @@
void* id) {
ASSERT(id == reinterpret_cast<void*>(1234));
NumberOfWeakCalls++;
- handle->Dispose(isolate);
+ handle->Dispose();
}
diff --git a/test/mjsunit/compiler/escape-analysis.js b/test/mjsunit/compiler/escape-analysis.js
index f32069c..7452e3b 100644
--- a/test/mjsunit/compiler/escape-analysis.js
+++ b/test/mjsunit/compiler/escape-analysis.js
@@ -200,3 +200,44 @@
check(27, 27); check(27, 27);
assertEquals(130, sum);
})();
+
+
+// Test OSR into a loop with captured objects.
+(function testOSR() {
+ function constructor() {
+ this.a = 23;
+ }
+ function osr1(length) {
+ assertEquals(23, (new constructor()).a);
+ var result = 0;
+ for (var i = 0; i < length; i++) {
+ result = (result + i) % 99;
+ }
+ return result;
+ }
+ function osr2(length) {
+ var result = 0;
+ for (var i = 0; i < length; i++) {
+ result = (result + i) % 99;
+ }
+ assertEquals(23, (new constructor()).a);
+ return result;
+ }
+ function osr3(length) {
+ var result = 0;
+ var o = new constructor();
+ for (var i = 0; i < length; i++) {
+ result = (result + i) % 99;
+ }
+ assertEquals(23, o.a);
+ return result;
+ }
+ function test(closure) {
+ assertEquals(45, closure(10));
+ assertEquals(45, closure(10));
+ assertEquals(10, closure(50000));
+ }
+ test(osr1);
+ test(osr2);
+ test(osr3);
+})();
diff --git a/test/mjsunit/debug-stepin-positions.js b/test/mjsunit/debug-stepin-positions.js
index 482e21b..e6d8204 100644
--- a/test/mjsunit/debug-stepin-positions.js
+++ b/test/mjsunit/debug-stepin-positions.js
@@ -30,26 +30,35 @@
Debug = debug.Debug
function DebuggerStatement() {
- debugger;
+ debugger; /*pause*/
}
-function TestCase(fun) {
+function TestCase(fun, frame_number) {
var exception = false;
var codeSnippet = undefined;
var resultPositions = undefined;
function listener(event, exec_state, event_data, data) {
try {
- if (event == Debug.DebugEvent.Break) {
+ if (event == Debug.DebugEvent.Break ||
+ event == Debug.DebugEvent.Exception) {
Debug.setListener(null);
-
- var secondFrame = exec_state.frame(1);
- codeSnippet = secondFrame.sourceLineText();
- resultPositions = secondFrame.stepInPositions();
+ assertHasLineMark(/pause/, exec_state.frame(0));
+ assertHasLineMark(/positions/, exec_state.frame(frame_number));
+ var frame = exec_state.frame(frame_number);
+ codeSnippet = frame.sourceLineText();
+ resultPositions = frame.stepInPositions();
}
} catch (e) {
exception = e
}
+
+ function assertHasLineMark(mark, frame) {
+ var line = frame.sourceLineText();
+ if (!mark.exec(frame.sourceLineText())) {
+ throw new Error("Line " + line + " should contain mark " + mark);
+ }
+ }
}
Debug.setListener(listener);
@@ -101,26 +110,98 @@
decoratedResult);
}
+function TestCaseWithDebugger(fun) {
+ TestCase(fun, 1);
+}
+
+function TestCaseWithBreakpoint(fun, line_number, frame_number) {
+ var breakpointId = Debug.setBreakPoint(fun, line_number);
+ TestCase(fun, frame_number);
+ Debug.clearBreakPoint(breakpointId);
+}
+
+function TestCaseWithException(fun, frame_number) {
+ Debug.setBreakOnException();
+ TestCase(fun, frame_number);
+ Debug.clearBreakOnException();
+}
+
// Test cases.
+// Step in position, when the function call that we are standing at is already
+// being executed.
+var fun = function() {
+ function g(p) {
+ throw String(p); /*pause*/
+ }
+ try {
+ var res = [ g(1), /*#*/g(2) ]; /*positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithBreakpoint(fun, 2, 1);
+TestCaseWithException(fun, 1);
+
+
+// Step in position, when the function call that we are standing at is raising
+// an exception.
+var fun = function() {
+ var o = {
+ g: function(p) {
+ throw p;
+ }
+ };
+ try {
+ var res = [ /*#*/f(1), /*#*/g(2) ]; /*pause, positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithException(fun, 0);
+
+
+// Step-in position, when already paused almost on the first call site.
+var fun = function() {
+ function g(p) {
+ throw p;
+ }
+ try {
+ var res = [ /*#*/g(Math.rand), /*#*/g(2) ]; /*pause, positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithBreakpoint(fun, 5, 0);
+
+// Step-in position, when already paused on the first call site.
+var fun = function() {
+ function g() {
+ throw "Debug";
+ }
+ try {
+ var res = [ /*#*/g(), /*#*/g() ]; /*pause, positions*/
+ } catch (e) {
+ }
+};
+TestCaseWithBreakpoint(fun, 5, 0);
+
+
// Method calls.
var fun = function() {
var data = {
a: function() {}
};
- var res = [ DebuggerStatement(), data./*#*/a(), data[/*#*/String("a")]/*#*/(), data["a"]/*#*/(), data.a, data["a"] ];
+ var res = [ DebuggerStatement(), data./*#*/a(), data[/*#*/String("a")]/*#*/(), data["a"]/*#*/(), data.a, data["a"] ]; /*positions*/
};
-TestCase(fun);
+TestCaseWithDebugger(fun);
// Function call on a value.
var fun = function() {
function g(p) {
return g;
}
- var res = [ DebuggerStatement(), /*#*/g(2), /*#*/g(2)/*#*/(3), /*#*/g(0)/*#*/(0)/*#*/(g) ];
+ var res = [ DebuggerStatement(), /*#*/g(2), /*#*/g(2)/*#*/(3), /*#*/g(0)/*#*/(0)/*#*/(g) ]; /*positions*/
};
-TestCase(fun);
+TestCaseWithDebugger(fun);
// Local function call, closure function call,
// local function construction call.
@@ -128,15 +209,17 @@
return function() {
function f(a, b) {
}
- var res = /*#*/f(DebuggerStatement(), /*#*/p(/*#*/new f()));
+ var res = /*#*/f(DebuggerStatement(), /*#*/p(/*#*/new f())); /*positions*/
};
})(Object);
-TestCase(fun);
+TestCaseWithDebugger(fun);
// Global function, global object construction, calls before pause point.
var fun = (function(p) {
return function() {
- var res = [ Math.abs(new Object()), DebuggerStatement(), Math./*#*/abs(4), /*#*/new Object()./*#*/toString() ];
+ var res = [ Math.abs(new Object()), DebuggerStatement(), Math./*#*/abs(4), /*#*/new Object()./*#*/toString() ]; /*positions*/
};
})(Object);
-TestCase(fun);
+TestCaseWithDebugger(fun);
+
+
diff --git a/test/cctest/test-lock.cc b/test/mjsunit/regress/regress-store-uncacheable.js
similarity index 69%
rename from test/cctest/test-lock.cc
rename to test/mjsunit/regress/regress-store-uncacheable.js
index 0603e44..e9c9fc2 100644
--- a/test/cctest/test-lock.cc
+++ b/test/mjsunit/regress/regress-store-uncacheable.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -24,39 +24,17 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Tests of the TokenLock class from lock.h
-#include <stdlib.h>
+// Flags: --allow-natives-syntax
-#include "v8.h"
-
-#include "platform.h"
-#include "cctest.h"
-
-
-using namespace ::v8::internal;
-
-
-TEST(SemaphoreTimeout) {
- bool ok;
- Semaphore* sem = OS::CreateSemaphore(0);
-
- // Semaphore not signalled - timeout.
- ok = sem->Wait(0);
- CHECK(!ok);
- ok = sem->Wait(100);
- CHECK(!ok);
- ok = sem->Wait(1000);
- CHECK(!ok);
-
- // Semaphore signalled - no timeout.
- sem->Signal();
- ok = sem->Wait(0);
- sem->Signal();
- ok = sem->Wait(100);
- sem->Signal();
- ok = sem->Wait(1000);
- CHECK(ok);
- delete sem;
+function f() {
+ var o = {};
+ o["<abc>"] = 123;
}
+
+f();
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
+assertOptimized(f);
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index ca81736..8548efe 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -441,8 +441,12 @@
'../../src/platform/time.h',
'../../src/platform-posix.h',
'../../src/platform.h',
+ '../../src/platform/condition-variable.cc',
+ '../../src/platform/condition-variable.h',
'../../src/platform/mutex.cc',
'../../src/platform/mutex.h',
+ '../../src/platform/semaphore.cc',
+ '../../src/platform/semaphore.h',
'../../src/preparse-data-format.h',
'../../src/preparse-data.cc',
'../../src/preparse-data.h',