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(&current_time, NULL) == -1) {
-    return false;
-  }
-
-  // Calculate time for end of timeout.
-  struct timeval end_time;
-  timeradd(&current_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(&current_time, NULL) == -1) {
-    return false;
-  }
-
-  // Calculate time for end of timeout.
-  struct timeval end_time;
-  timeradd(&current_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(&current_time, NULL) == -1) {
-    return false;
-  }
-
-  // Calculate time for end of timeout.
-  struct timeval end_time;
-  timeradd(&current_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(&current_time, NULL) == -1) {
-    return false;
-  }
-
-  // Calculate time for end of timeout.
-  struct timeval end_time;
-  timeradd(&current_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(&current_time, NULL) == -1) {
-    return false;
-  }
-
-  // Calculate time for end of timeout.
-  struct timeval end_time;
-  timeradd(&current_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',