Version 3.24.4

Removed all stuff marked as V8_DEPRECATED.

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@18354 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/allocation-tracker.cc b/src/allocation-tracker.cc
index 8044cef..59ba6c9 100644
--- a/src/allocation-tracker.cc
+++ b/src/allocation-tracker.cc
@@ -246,16 +246,15 @@
       info_(info) {
   script_ = Handle<Script>::cast(
       script->GetIsolate()->global_handles()->Create(script));
-  GlobalHandles::MakeWeak(
-      reinterpret_cast<Object**>(script_.location()),
-      this, &HandleWeakScript);
+  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
+                          this,
+                          &HandleWeakScript);
 }
 
 
 AllocationTracker::UnresolvedLocation::~UnresolvedLocation() {
   if (!script_.is_null()) {
-    script_->GetIsolate()->global_handles()->Destroy(
-        reinterpret_cast<Object**>(script_.location()));
+    GlobalHandles::Destroy(reinterpret_cast<Object**>(script_.location()));
   }
 }
 
@@ -268,12 +267,11 @@
 
 
 void AllocationTracker::UnresolvedLocation::HandleWeakScript(
-    v8::Isolate* isolate,
-    v8::Persistent<v8::Value>* obj,
-    void* data) {
-  UnresolvedLocation* location = reinterpret_cast<UnresolvedLocation*>(data);
-  location->script_ = Handle<Script>::null();
-  obj->Reset();
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  UnresolvedLocation* loc =
+      reinterpret_cast<UnresolvedLocation*>(data.GetParameter());
+  GlobalHandles::Destroy(reinterpret_cast<Object**>(loc->script_.location()));
+  loc->script_ = Handle<Script>::null();
 }
 
 
diff --git a/src/allocation-tracker.h b/src/allocation-tracker.h
index 6844716..1a5dc9e 100644
--- a/src/allocation-tracker.h
+++ b/src/allocation-tracker.h
@@ -112,9 +112,9 @@
     void Resolve();
 
    private:
-    static void HandleWeakScript(v8::Isolate* isolate,
-                                 v8::Persistent<v8::Value>* obj,
-                                 void* data);
+    static void HandleWeakScript(
+        const v8::WeakCallbackData<v8::Value, void>& data);
+
     Handle<Script> script_;
     int start_position_;
     FunctionInfo* info_;
diff --git a/src/api.cc b/src/api.cc
index 02b6be4..9a68f63 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -472,11 +472,6 @@
 }
 
 
-v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
-  return v8::Isolate::GetCurrent()->ThrowException(value);
-}
-
-
 RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
 
 
@@ -523,42 +518,6 @@
 }
 
 
-v8::Handle<Primitive> Undefined() {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
-    return v8::Handle<v8::Primitive>();
-  }
-  return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
-}
-
-
-v8::Handle<Primitive> Null() {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
-    return v8::Handle<v8::Primitive>();
-  }
-  return ToApiHandle<Primitive>(isolate->factory()->null_value());
-}
-
-
-v8::Handle<Boolean> True() {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
-    return v8::Handle<Boolean>();
-  }
-  return ToApiHandle<Boolean>(isolate->factory()->true_value());
-}
-
-
-v8::Handle<Boolean> False() {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
-    return v8::Handle<Boolean>();
-  }
-  return ToApiHandle<Boolean>(isolate->factory()->false_value());
-}
-
-
 ResourceConstraints::ResourceConstraints()
   : max_young_space_size_(0),
     max_old_space_size_(0),
@@ -605,11 +564,6 @@
 }
 
 
-void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory) {
-  ConfigureDefaults(physical_memory, i::CPU::NumberOfProcessorsOnline());
-}
-
-
 bool SetResourceConstraints(Isolate* v8_isolate,
                             ResourceConstraints* constraints) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
@@ -655,12 +609,8 @@
 
 void V8::MakeWeak(i::Object** object,
                   void* parameters,
-                  WeakCallback weak_callback,
-                  RevivableCallback weak_reference_callback) {
-  i::GlobalHandles::MakeWeak(object,
-                             parameters,
-                             weak_callback,
-                             weak_reference_callback);
+                  WeakCallback weak_callback) {
+  i::GlobalHandles::MakeWeak(object, parameters, weak_callback);
 }
 
 
@@ -703,20 +653,12 @@
   isolate_ = internal_isolate;
   prev_next_ = current->next;
   prev_limit_ = current->limit;
-  is_closed_ = false;
   current->level++;
 }
 
 
 HandleScope::~HandleScope() {
-  if (!is_closed_) {
-    Leave();
-  }
-}
-
-
-void HandleScope::Leave() {
-  return i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
+  i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
 }
 
 
@@ -859,32 +801,6 @@
 }
 
 
-i::Object** v8::HandleScope::RawClose(i::Object** value) {
-  if (!ApiCheck(!is_closed_,
-                "v8::HandleScope::Close()",
-                "Local scope has already been closed")) {
-    return 0;
-  }
-  LOG_API(isolate_, "CloseHandleScope");
-
-  // Read the result before popping the handle block.
-  i::Object* result = NULL;
-  if (value != NULL) {
-    result = *value;
-  }
-  is_closed_ = true;
-  Leave();
-
-  if (value == NULL) {
-    return NULL;
-  }
-
-  // Allocate a new handle on the previous handle block.
-  i::Handle<i::Object> handle(result, isolate_);
-  return handle.location();
-}
-
-
 // --- N e a n d e r ---
 
 
@@ -1124,12 +1040,6 @@
 }
 
 
-Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
-      int argc, Handle<FunctionTemplate> argv[]) {
-  return New(Isolate::GetCurrent(), receiver, argc, argv);
-}
-
-
 Local<AccessorSignature> AccessorSignature::New(
       Isolate* isolate,
       Handle<FunctionTemplate> receiver) {
@@ -1137,13 +1047,6 @@
 }
 
 
-// While this is just a cast, it's lame not to use an Isolate parameter.
-Local<AccessorSignature> AccessorSignature::New(
-      Handle<FunctionTemplate> receiver) {
-  return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
-}
-
-
 template<typename Operation>
 static Local<Operation> NewDescriptor(
     Isolate* isolate,
@@ -1465,13 +1368,15 @@
 // Ensure that the object template has a constructor.  If no
 // constructor is available we create one.
 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
+    i::Isolate* isolate,
     ObjectTemplate* object_template) {
   i::Object* obj = Utils::OpenHandle(object_template)->constructor();
   if (!obj ->IsUndefined()) {
     i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
-    return i::Handle<i::FunctionTemplateInfo>(info, info->GetIsolate());
+    return i::Handle<i::FunctionTemplateInfo>(info, isolate);
   }
-  Local<FunctionTemplate> templ = FunctionTemplate::New();
+  Local<FunctionTemplate> templ =
+      FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
   constructor->set_instance_template(*Utils::OpenHandle(object_template));
   Utils::OpenHandle(object_template)->set_constructor(*constructor);
@@ -1493,6 +1398,7 @@
 
 
 static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
+    i::Isolate* isolate,
     Template* template_obj) {
   return Utils::OpenHandle(template_obj);
 }
@@ -1500,8 +1406,9 @@
 
 // TODO(dcarney): remove this with ObjectTemplate::SetAccessor
 static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
+    i::Isolate* isolate,
     ObjectTemplate* object_template) {
-  EnsureConstructor(object_template);
+  EnsureConstructor(isolate, object_template);
   return Utils::OpenHandle(object_template);
 }
 
@@ -1522,7 +1429,7 @@
   i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
       name, getter, setter, data, settings, attribute, signature);
   if (obj.is_null()) return false;
-  i::Handle<i::TemplateInfo> info = GetTemplateInfo(template_obj);
+  i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
   AddPropertyToTemplate(info, obj);
   return true;
 }
@@ -1574,7 +1481,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(this);
+  EnsureConstructor(isolate, this);
   i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
       Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
@@ -1601,7 +1508,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(this);
+  EnsureConstructor(isolate, this);
   i::FunctionTemplateInfo* constructor =
       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
@@ -1617,7 +1524,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(this);
+  EnsureConstructor(isolate, this);
 
   i::Handle<i::Struct> struct_info =
       isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
@@ -1650,7 +1557,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(this);
+  EnsureConstructor(isolate, this);
   i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
       Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
@@ -1678,7 +1585,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(this);
+  EnsureConstructor(isolate, this);
   i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
       Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
@@ -1712,7 +1619,7 @@
     // The internal field count is set by the constructor function's
     // construct code, so we ensure that there is a constructor
     // function to do the setting.
-    EnsureConstructor(this);
+    EnsureConstructor(isolate, this);
   }
   Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
 }
@@ -1920,25 +1827,6 @@
 }
 
 
-Local<Value> Script::Id() {
-  i::Handle<i::HeapObject> obj =
-      i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
-  i::Isolate* isolate = obj->GetIsolate();
-  ON_BAILOUT(isolate, "v8::Script::Id()", return Local<Value>());
-  LOG_API(isolate, "Script::Id");
-  i::Object* raw_id = NULL;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::SharedFunctionInfo> function_info = OpenScript(this);
-    i::Handle<i::Script> script(i::Script::cast(function_info->script()));
-    i::Handle<i::Object> id(script->id(), isolate);
-    raw_id = *id;
-  }
-  i::Handle<i::Object> id(raw_id, isolate);
-  return Utils::ToLocal(id);
-}
-
-
 int Script::GetId() {
   i::Handle<i::HeapObject> obj =
       i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
@@ -2321,11 +2209,6 @@
 }
 
 
-void Message::PrintCurrentStackTrace(FILE* out) {
-  PrintCurrentStackTrace(Isolate::GetCurrent(), out);
-}
-
-
 // --- S t a c k T r a c e ---
 
 Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
@@ -2365,12 +2248,6 @@
 }
 
 
-Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
-    StackTraceOptions options) {
-  return CurrentStackTrace(Isolate::GetCurrent(), frame_limit, options);
-}
-
-
 // --- S t a c k F r a m e ---
 
 int StackFrame::GetLineNumber() const {
@@ -4286,17 +4163,6 @@
 }
 
 
-Handle<Value> Function::GetScriptId() const {
-  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
-  i::Isolate* isolate = func->GetIsolate();
-  if (!func->shared()->script()->IsScript()) {
-    return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
-  }
-  i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
-  return Utils::ToLocal(i::Handle<i::Object>(script->id(), isolate));
-}
-
-
 int Function::ScriptId() const {
   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   if (!func->shared()->script()->IsScript()) return v8::Script::kNoScriptId;
@@ -5278,11 +5144,11 @@
 
     if (!global_template.IsEmpty()) {
       // Make sure that the global_template has a constructor.
-      global_constructor = EnsureConstructor(*global_template);
+      global_constructor = EnsureConstructor(isolate, *global_template);
 
       // Create a fresh template for the global proxy object.
       proxy_template = ObjectTemplate::New();
-      proxy_constructor = EnsureConstructor(*proxy_template);
+      proxy_constructor = EnsureConstructor(isolate, *proxy_template);
 
       // Set the global template to be the prototype template of
       // global proxy template.
@@ -5373,38 +5239,12 @@
 }
 
 
-bool Context::InContext() {
-  return i::Isolate::Current()->context() != NULL;
-}
-
-
 v8::Isolate* Context::GetIsolate() {
   i::Handle<i::Context> env = Utils::OpenHandle(this);
   return reinterpret_cast<Isolate*>(env->GetIsolate());
 }
 
 
-v8::Local<v8::Context> Context::GetEntered() {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
-    return Local<Context>();
-  }
-  return reinterpret_cast<Isolate*>(isolate)->GetEnteredContext();
-}
-
-
-v8::Local<v8::Context> Context::GetCurrent() {
-  i::Isolate* isolate = i::Isolate::Current();
-  return reinterpret_cast<Isolate*>(isolate)->GetCurrentContext();
-}
-
-
-v8::Local<v8::Context> Context::GetCalling() {
-  i::Isolate* isolate = i::Isolate::Current();
-  return reinterpret_cast<Isolate*>(isolate)->GetCallingContext();
-}
-
-
 v8::Local<v8::Object> Context::Global() {
   i::Handle<i::Context> context = Utils::OpenHandle(this);
   i::Isolate* isolate = context->GetIsolate();
@@ -5499,11 +5339,6 @@
 }
 
 
-Local<External> v8::External::New(void* value) {
-  return v8::External::New(Isolate::GetCurrent(), value);
-}
-
-
 void* External::Value() const {
   return ExternalValue(*Utils::OpenHandle(this));
 }
@@ -5695,12 +5530,6 @@
 }
 
 
-Local<String> v8::String::NewExternal(
-      v8::String::ExternalStringResource* resource) {
-  return NewExternal(Isolate::GetCurrent(), resource);
-}
-
-
 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
   i::Handle<i::String> obj = Utils::OpenHandle(this);
   i::Isolate* isolate = obj->GetIsolate();
@@ -5752,12 +5581,6 @@
 }
 
 
-Local<String> v8::String::NewExternal(
-      v8::String::ExternalAsciiStringResource* resource) {
-  return NewExternal(Isolate::GetCurrent(), resource);
-}
-
-
 bool v8::String::MakeExternal(
     v8::String::ExternalAsciiStringResource* resource) {
   i::Handle<i::String> obj = Utils::OpenHandle(this);
@@ -5840,11 +5663,6 @@
 }
 
 
-Local<v8::Value> v8::NumberObject::New(double value) {
-  return New(Isolate::GetCurrent(), value);
-}
-
-
 double v8::NumberObject::ValueOf() const {
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "NumberObject::NumberValue");
@@ -5936,11 +5754,6 @@
 }
 
 
-Local<v8::Value> v8::Date::New(double time) {
-  return New(Isolate::GetCurrent(), time);
-}
-
-
 double v8::Date::ValueOf() const {
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "Date::NumberValue");
@@ -5986,11 +5799,6 @@
 }
 
 
-void v8::Date::DateTimeConfigurationChangeNotification() {
-  DateTimeConfigurationChangeNotification(Isolate::GetCurrent());
-}
-
-
 static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
   i::Isolate* isolate = i::Isolate::Current();
   uint8_t flags_buf[3];
@@ -6056,11 +5864,6 @@
 }
 
 
-Local<v8::Array> v8::Array::New(int length) {
-  return New(Isolate::GetCurrent(), length);
-}
-
-
 uint32_t v8::Array::Length() const {
   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
   i::Object* length = obj->length();
@@ -6156,11 +5959,6 @@
 }
 
 
-Local<ArrayBuffer> v8::ArrayBuffer::New(size_t byte_length) {
-  return New(Isolate::GetCurrent(), byte_length);
-}
-
-
 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
                                         size_t byte_length) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@@ -6174,11 +5972,6 @@
 }
 
 
-Local<ArrayBuffer> v8::ArrayBuffer::New(void* data, size_t byte_length) {
-  return New(Isolate::GetCurrent(), data, byte_length);
-}
-
-
 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
   ASSERT(obj->buffer()->IsJSArrayBuffer());
@@ -6511,16 +6304,6 @@
 }
 
 
-int64_t V8::AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes) {
-  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
-  if (isolate == NULL || !isolate->IsInitialized()) {
-    return 0;
-  }
-  Isolate* isolate_ext = reinterpret_cast<Isolate*>(isolate);
-  return isolate_ext->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
-}
-
-
 HeapProfiler* Isolate::GetHeapProfiler() {
   i::HeapProfiler* heap_profiler =
       reinterpret_cast<i::Isolate*>(this)->heap_profiler();
@@ -6793,27 +6576,6 @@
 }
 
 
-String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj)
-    : str_(NULL), length_(0) {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (obj.IsEmpty()) return;
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  TryCatch try_catch;
-  Handle<String> str = obj->ToString();
-  if (str.IsEmpty()) return;
-  length_ = str->Utf8Length();
-  str_ = i::NewArray<char>(length_ + 1);
-  str->WriteUtf8(str_);
-  ASSERT(i::String::NonAsciiStart(str_, length_) >= length_);
-}
-
-
-String::AsciiValue::~AsciiValue() {
-  i::DeleteArray(str_);
-}
-
-
 String::Value::Value(v8::Handle<v8::Value> obj)
     : str_(NULL), length_(0) {
   i::Isolate* isolate = i::Isolate::Current();
@@ -7205,11 +6967,6 @@
 }
 
 
-unsigned CpuProfile::GetUid() const {
-  return reinterpret_cast<const i::CpuProfile*>(this)->uid();
-}
-
-
 Handle<String> CpuProfile::GetTitle() const {
   i::Isolate* isolate = i::Isolate::Current();
   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
@@ -7247,11 +7004,6 @@
 }
 
 
-int CpuProfiler::GetProfileCount() {
-  return reinterpret_cast<i::CpuProfiler*>(this)->GetProfilesCount();
-}
-
-
 void CpuProfiler::SetSamplingInterval(int us) {
   ASSERT(us >= 0);
   return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
@@ -7259,12 +7011,6 @@
 }
 
 
-const CpuProfile* CpuProfiler::GetCpuProfile(int index) {
-  return reinterpret_cast<const CpuProfile*>(
-      reinterpret_cast<i::CpuProfiler*>(this)->GetProfile(index));
-}
-
-
 void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
   reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
       *Utils::OpenHandle(*title), record_samples);
@@ -7278,11 +7024,6 @@
 }
 
 
-void CpuProfiler::DeleteAllCpuProfiles() {
-  reinterpret_cast<i::CpuProfiler*>(this)->DeleteAllProfiles();
-}
-
-
 void CpuProfiler::SetIdle(bool is_idle) {
   i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
   i::StateTag state = isolate->current_vm_state();
@@ -7477,6 +7218,19 @@
 }
 
 
+Handle<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
+  i::Handle<i::Object> obj =
+      reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
+  if (obj.is_null()) return Local<Value>();
+  return Utils::ToLocal(obj);
+}
+
+
+void HeapProfiler::ClearObjectIds() {
+  reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
+}
+
+
 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
     Handle<String> title,
     ActivityControl* control,
@@ -7527,16 +7281,6 @@
 }
 
 
-void HeapProfiler::StartRecordingHeapAllocations() {
-  reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(true);
-}
-
-
-void HeapProfiler::StopRecordingHeapAllocations() {
-  reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
-}
-
-
 v8::Testing::StressType internal::Testing::stress_type_ =
     v8::Testing::kStressTypeOpt;
 
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 4eb08a1..5c149de 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1231,216 +1231,6 @@
 }
 
 
-void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
-  // Untagged case: double input in d2, double result goes
-  //   into d2.
-  // Tagged case: tagged input on top of stack and in r0,
-  //   tagged result (heap number) goes into r0.
-
-  Label input_not_smi;
-  Label loaded;
-  Label calculate;
-  Label invalid_cache;
-  const Register scratch0 = r9;
-  Register scratch1 = no_reg;  // will be r4
-  const Register cache_entry = r0;
-  const bool tagged = (argument_type_ == TAGGED);
-
-  if (tagged) {
-    // Argument is a number and is on stack and in r0.
-    // Load argument and check if it is a smi.
-    __ JumpIfNotSmi(r0, &input_not_smi);
-
-    // Input is a smi. Convert to double and load the low and high words
-    // of the double into r2, r3.
-    __ SmiToDouble(d7, r0);
-    __ vmov(r2, r3, d7);
-    __ b(&loaded);
-
-    __ bind(&input_not_smi);
-    // Check if input is a HeapNumber.
-    __ CheckMap(r0,
-                r1,
-                Heap::kHeapNumberMapRootIndex,
-                &calculate,
-                DONT_DO_SMI_CHECK);
-    // Input is a HeapNumber. Load it to a double register and store the
-    // low and high words into r2, r3.
-    __ vldr(d0, FieldMemOperand(r0, HeapNumber::kValueOffset));
-    __ vmov(r2, r3, d0);
-  } else {
-    // Input is untagged double in d2. Output goes to d2.
-    __ vmov(r2, r3, d2);
-  }
-  __ bind(&loaded);
-  // r2 = low 32 bits of double value
-  // r3 = high 32 bits of double value
-  // Compute hash (the shifts are arithmetic):
-  //   h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
-  __ eor(r1, r2, Operand(r3));
-  __ eor(r1, r1, Operand(r1, ASR, 16));
-  __ eor(r1, r1, Operand(r1, ASR, 8));
-  ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
-  __ And(r1, r1, Operand(TranscendentalCache::SubCache::kCacheSize - 1));
-
-  // r2 = low 32 bits of double value.
-  // r3 = high 32 bits of double value.
-  // r1 = TranscendentalCache::hash(double value).
-  Isolate* isolate = masm->isolate();
-  ExternalReference cache_array =
-      ExternalReference::transcendental_cache_array_address(isolate);
-  __ mov(cache_entry, Operand(cache_array));
-  // cache_entry points to cache array.
-  int cache_array_index
-      = type_ * sizeof(isolate->transcendental_cache()->caches_[0]);
-  __ ldr(cache_entry, MemOperand(cache_entry, cache_array_index));
-  // r0 points to the cache for the type type_.
-  // If NULL, the cache hasn't been initialized yet, so go through runtime.
-  __ cmp(cache_entry, Operand::Zero());
-  __ b(eq, &invalid_cache);
-
-#ifdef DEBUG
-  // Check that the layout of cache elements match expectations.
-  { TranscendentalCache::SubCache::Element test_elem[2];
-    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
-    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
-    char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0]));
-    char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1]));
-    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
-    CHECK_EQ(12, elem2_start - elem_start);  // Two uint_32's and a pointer.
-    CHECK_EQ(0, elem_in0 - elem_start);
-    CHECK_EQ(kIntSize, elem_in1 - elem_start);
-    CHECK_EQ(2 * kIntSize, elem_out - elem_start);
-  }
-#endif
-
-  // Find the address of the r1'st entry in the cache, i.e., &r0[r1*12].
-  __ add(r1, r1, Operand(r1, LSL, 1));
-  __ add(cache_entry, cache_entry, Operand(r1, LSL, 2));
-  // Check if cache matches: Double value is stored in uint32_t[2] array.
-  __ ldm(ia, cache_entry, r4.bit() | r5.bit() | r6.bit());
-  __ cmp(r2, r4);
-  __ cmp(r3, r5, eq);
-  __ b(ne, &calculate);
-
-  scratch1 = r4;  // Start of scratch1 range.
-
-  // Cache hit. Load result, cleanup and return.
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(
-      counters->transcendental_cache_hit(), 1, scratch0, scratch1);
-  if (tagged) {
-    // Pop input value from stack and load result into r0.
-    __ pop();
-    __ mov(r0, Operand(r6));
-  } else {
-    // Load result into d2.
-    __ vldr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset));
-  }
-  __ Ret();
-
-  __ bind(&calculate);
-  __ IncrementCounter(
-      counters->transcendental_cache_miss(), 1, scratch0, scratch1);
-  if (tagged) {
-    __ bind(&invalid_cache);
-    ExternalReference runtime_function =
-        ExternalReference(RuntimeFunction(), masm->isolate());
-    __ TailCallExternalReference(runtime_function, 1, 1);
-  } else {
-    Label no_update;
-    Label skip_cache;
-
-    // Call C function to calculate the result and update the cache.
-    // r0: precalculated cache entry address.
-    // r2 and r3: parts of the double value.
-    // Store r0, r2 and r3 on stack for later before calling C function.
-    __ Push(r3, r2, cache_entry);
-    GenerateCallCFunction(masm, scratch0);
-    __ GetCFunctionDoubleResult(d2);
-
-    // Try to update the cache. If we cannot allocate a
-    // heap number, we return the result without updating.
-    __ Pop(r3, r2, cache_entry);
-    __ LoadRoot(r5, Heap::kHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(r6, scratch0, scratch1, r5, &no_update);
-    __ vstr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset));
-    __ stm(ia, cache_entry, r2.bit() | r3.bit() | r6.bit());
-    __ Ret();
-
-    __ bind(&invalid_cache);
-    // The cache is invalid. Call runtime which will recreate the
-    // cache.
-    __ LoadRoot(r5, Heap::kHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(r0, scratch0, scratch1, r5, &skip_cache);
-    __ vstr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset));
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-      __ push(r0);
-      __ CallRuntime(RuntimeFunction(), 1);
-    }
-    __ vldr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset));
-    __ Ret();
-
-    __ bind(&skip_cache);
-    // Call C function to calculate the result and answer directly
-    // without updating the cache.
-    GenerateCallCFunction(masm, scratch0);
-    __ GetCFunctionDoubleResult(d2);
-    __ bind(&no_update);
-
-    // We return the value in d2 without adding it to the cache, but
-    // we cause a scavenging GC so that future allocations will succeed.
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-
-      // Allocate an aligned object larger than a HeapNumber.
-      ASSERT(4 * kPointerSize >= HeapNumber::kSize);
-      __ mov(scratch0, Operand(4 * kPointerSize));
-      __ push(scratch0);
-      __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
-    }
-    __ Ret();
-  }
-}
-
-
-void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
-                                                    Register scratch) {
-  Isolate* isolate = masm->isolate();
-
-  __ push(lr);
-  __ PrepareCallCFunction(0, 1, scratch);
-  if (masm->use_eabi_hardfloat()) {
-    __ vmov(d0, d2);
-  } else {
-    __ vmov(r0, r1, d2);
-  }
-  AllowExternalCallThatCantCauseGC scope(masm);
-  switch (type_) {
-    case TranscendentalCache::LOG:
-      __ CallCFunction(ExternalReference::math_log_double_function(isolate),
-          0, 1);
-      break;
-    default:
-      UNIMPLEMENTED();
-      break;
-  }
-  __ pop(lr);
-}
-
-
-Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
-  switch (type_) {
-    // Add more cases when necessary.
-    case TranscendentalCache::LOG: return Runtime::kMath_log;
-    default:
-      UNIMPLEMENTED();
-      return Runtime::kAbort;
-  }
-}
-
-
 void MathPowStub::Generate(MacroAssembler* masm) {
   const Register base = r1;
   const Register exponent = r2;
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index e400686..6156384 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -37,30 +37,6 @@
 void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
 
 
-// Compute a transcendental math function natively, or call the
-// TranscendentalCache runtime function.
-class TranscendentalCacheStub: public PlatformCodeStub {
- public:
-  enum ArgumentType {
-    TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
-    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
-  };
-
-  TranscendentalCacheStub(TranscendentalCache::Type type,
-                          ArgumentType argument_type)
-      : type_(type), argument_type_(argument_type) { }
-  void Generate(MacroAssembler* masm);
- private:
-  TranscendentalCache::Type type_;
-  ArgumentType argument_type_;
-  void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
-
-  Major MajorKey() { return TranscendentalCache; }
-  int MinorKey() { return type_ | argument_type_; }
-  Runtime::FunctionId RuntimeFunction();
-};
-
-
 class StoreBufferOverflowStub: public PlatformCodeStub {
  public:
   explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 255e1f3..3ac30c5 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -37,15 +37,6 @@
 namespace internal {
 
 
-UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
-  switch (type) {
-    case TranscendentalCache::LOG: return &log;
-    default: UNIMPLEMENTED();
-  }
-  return NULL;
-}
-
-
 #define __ masm.
 
 
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index f6d3ea3..dbcce96 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1025,6 +1025,16 @@
     CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
     patch_site.EmitPatchInfo();
 
+    Label skip;
+    __ b(&skip);
+    PrepareForBailout(clause, TOS_REG);
+    __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+    __ cmp(r0, ip);
+    __ b(ne, &next_test);
+    __ Drop(1);
+    __ jmp(clause->body_target());
+    __ bind(&skip);
+
     __ cmp(r0, Operand::Zero());
     __ b(ne, &next_test);
     __ Drop(1);  // Switch value is no longer needed.
@@ -3698,13 +3708,11 @@
 
 
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
-  // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
-                               TranscendentalCacheStub::TAGGED);
+  // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallStub(&stub);
+  __ CallRuntime(Runtime::kMath_log, 1);
   context()->Plug(r0);
 }
 
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 5a1d55e..e2b29df 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1224,9 +1224,10 @@
 
 
 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
-  LOperand* input = UseFixedDouble(instr->value(), d2);
-  LMathLog* result = new(zone()) LMathLog(input);
-  return MarkAsCall(DefineFixedDouble(result, d2), instr);
+  ASSERT(instr->representation().IsDouble());
+  ASSERT(instr->value()->representation().IsDouble());
+  LOperand* input = UseFixedDouble(instr->value(), d0);
+  return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr);
 }
 
 
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 4bac4b1..5c32031 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -488,10 +488,6 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
   DECLARE_HYDROGEN_ACCESSOR(CallStub)
-
-  TranscendentalCache::Type transcendental_type() {
-    return hydrogen()->transcendental_type();
-  }
 };
 
 
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 8f1c9c0..ade6928 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1085,13 +1085,6 @@
       CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
       break;
     }
-    case CodeStub::TranscendentalCache: {
-      __ ldr(r0, MemOperand(sp, 0));
-      TranscendentalCacheStub stub(instr->transcendental_type(),
-                                   TranscendentalCacheStub::TAGGED);
-      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-      break;
-    }
     default:
       UNREACHABLE();
   }
@@ -2134,7 +2127,7 @@
       __ PrepareCallCFunction(0, 2, scratch0());
       __ SetCallCDoubleArguments(left, right);
       __ CallCFunction(
-          ExternalReference::double_fp_operation(Token::MOD, isolate()),
+          ExternalReference::mod_two_doubles_operation(isolate()),
           0, 2);
       // Move the result in the double result register.
       __ GetCFunctionDoubleResult(result);
@@ -3941,13 +3934,11 @@
 
 
 void LCodeGen::DoMathLog(LMathLog* instr) {
-  ASSERT(ToDoubleRegister(instr->result()).is(d2));
-  // Set the context register to a GC-safe fake value. Clobbering it is
-  // OK because this instruction is marked as a call.
-  __ mov(cp, Operand::Zero());
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
-                               TranscendentalCacheStub::UNTAGGED);
-  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+  __ PrepareCallCFunction(0, 1, scratch0());
+  __ SetCallCDoubleArguments(ToDoubleRegister(instr->value()));
+  __ CallCFunction(ExternalReference::math_log_double_function(isolate()),
+                   0, 1);
+  __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result()));
 }
 
 
diff --git a/src/assembler.cc b/src/assembler.cc
index b77e92d..4ac2fb4 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -1093,13 +1093,6 @@
 }
 
 
-ExternalReference ExternalReference::transcendental_cache_array_address(
-    Isolate* isolate) {
-  return ExternalReference(
-      isolate->transcendental_cache()->cache_array_address());
-}
-
-
 ExternalReference ExternalReference::new_deoptimizer_function(
     Isolate* isolate) {
   return ExternalReference(
@@ -1395,40 +1388,11 @@
 #endif  // V8_INTERPRETED_REGEXP
 
 
-static double add_two_doubles(double x, double y) {
-  return x + y;
-}
-
-
-static double sub_two_doubles(double x, double y) {
-  return x - y;
-}
-
-
-static double mul_two_doubles(double x, double y) {
-  return x * y;
-}
-
-
-static double div_two_doubles(double x, double y) {
-  return x / y;
-}
-
-
-static double mod_two_doubles(double x, double y) {
-  return modulo(x, y);
-}
-
-
-static double math_log_double(double x) {
-  return log(x);
-}
-
-
 ExternalReference ExternalReference::math_log_double_function(
     Isolate* isolate) {
+  typedef double (*d2d)(double x);
   return ExternalReference(Redirect(isolate,
-                                    FUNCTION_ADDR(math_log_double),
+                                    FUNCTION_ADDR(static_cast<d2d>(log)),
                                     BUILTIN_FP_CALL));
 }
 
@@ -1533,12 +1497,6 @@
 }
 
 
-static int native_compare_doubles(double y, double x) {
-  if (x == y) return EQUAL;
-  return x < y ? LESS : GREATER;
-}
-
-
 bool EvalComparison(Token::Value op, double op1, double op2) {
   ASSERT(Token::IsCompareOp(op));
   switch (op) {
@@ -1556,42 +1514,14 @@
 }
 
 
-ExternalReference ExternalReference::double_fp_operation(
-    Token::Value operation, Isolate* isolate) {
-  typedef double BinaryFPOperation(double x, double y);
-  BinaryFPOperation* function = NULL;
-  switch (operation) {
-    case Token::ADD:
-      function = &add_two_doubles;
-      break;
-    case Token::SUB:
-      function = &sub_two_doubles;
-      break;
-    case Token::MUL:
-      function = &mul_two_doubles;
-      break;
-    case Token::DIV:
-      function = &div_two_doubles;
-      break;
-    case Token::MOD:
-      function = &mod_two_doubles;
-      break;
-    default:
-      UNREACHABLE();
-  }
+ExternalReference ExternalReference::mod_two_doubles_operation(
+    Isolate* isolate) {
   return ExternalReference(Redirect(isolate,
-                                    FUNCTION_ADDR(function),
+                                    FUNCTION_ADDR(modulo),
                                     BUILTIN_FP_FP_CALL));
 }
 
 
-ExternalReference ExternalReference::compare_doubles(Isolate* isolate) {
-  return ExternalReference(Redirect(isolate,
-                                    FUNCTION_ADDR(native_compare_doubles),
-                                    BUILTIN_COMPARE_CALL));
-}
-
-
 #ifdef ENABLE_DEBUGGER_SUPPORT
 ExternalReference ExternalReference::debug_break(Isolate* isolate) {
   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(Debug_Break)));
diff --git a/src/assembler.h b/src/assembler.h
index 6c06262..3ccfccf 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -718,7 +718,6 @@
       Isolate* isolate);
   static ExternalReference flush_icache_function(Isolate* isolate);
   static ExternalReference perform_gc_function(Isolate* isolate);
-  static ExternalReference transcendental_cache_array_address(Isolate* isolate);
   static ExternalReference delete_handle_scope_extensions(Isolate* isolate);
 
   static ExternalReference get_date_field_function(Isolate* isolate);
@@ -784,9 +783,7 @@
   static ExternalReference new_space_high_promotion_mode_active_address(
       Isolate* isolate);
 
-  static ExternalReference double_fp_operation(Token::Value operation,
-                                               Isolate* isolate);
-  static ExternalReference compare_doubles(Isolate* isolate);
+  static ExternalReference mod_two_doubles_operation(Isolate* isolate);
   static ExternalReference power_double_double_function(Isolate* isolate);
   static ExternalReference power_double_int_function(Isolate* isolate);
 
diff --git a/src/ast.cc b/src/ast.cc
index 681b3d4..ecf83ea 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1121,7 +1121,7 @@
                        Expression* label,
                        ZoneList<Statement*>* statements,
                        int pos)
-    : AstNode(pos),
+    : Expression(isolate, pos),
       label_(label),
       statements_(statements),
       compare_type_(Type::None(), isolate),
diff --git a/src/ast.h b/src/ast.h
index 4e413c5..cf3ef92 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -115,17 +115,14 @@
   V(CountOperation)                             \
   V(BinaryOperation)                            \
   V(CompareOperation)                           \
-  V(ThisFunction)
-
-#define AUXILIARY_NODE_LIST(V)                  \
+  V(ThisFunction)                               \
   V(CaseClause)
 
 #define AST_NODE_LIST(V)                        \
   DECLARATION_NODE_LIST(V)                      \
   MODULE_NODE_LIST(V)                           \
   STATEMENT_NODE_LIST(V)                        \
-  EXPRESSION_NODE_LIST(V)                       \
-  AUXILIARY_NODE_LIST(V)
+  EXPRESSION_NODE_LIST(V)
 
 // Forward declarations
 class AstConstructionVisitor;
@@ -1105,7 +1102,7 @@
 };
 
 
-class CaseClause V8_FINAL : public AstNode {
+class CaseClause V8_FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(CaseClause)
 
@@ -1147,16 +1144,11 @@
   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
     tag_ = tag;
     cases_ = cases;
-    switch_type_ = UNKNOWN_SWITCH;
   }
 
   Expression* tag() const { return tag_; }
   ZoneList<CaseClause*>* cases() const { return cases_; }
 
-  enum SwitchType { UNKNOWN_SWITCH, SMI_SWITCH, STRING_SWITCH, GENERIC_SWITCH };
-  SwitchType switch_type() const { return switch_type_; }
-  void set_switch_type(SwitchType switch_type) { switch_type_ = switch_type; }
-
  protected:
   SwitchStatement(Isolate* isolate, ZoneStringList* labels, int pos)
       : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS, pos),
@@ -1166,7 +1158,6 @@
  private:
   Expression* tag_;
   ZoneList<CaseClause*>* cases_;
-  SwitchType switch_type_;
 };
 
 
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index ac3fbb0..0a9fdcb 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1302,7 +1302,7 @@
   native_context()->set_out_of_memory(heap->false_value());
 
   // Initialize the embedder data slot.
-  Handle<FixedArray> embedder_data = factory->NewFixedArray(2);
+  Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
   native_context()->set_embedder_data(*embedder_data);
 }
 
diff --git a/src/code-stubs.h b/src/code-stubs.h
index bedf295..2ab62b0 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -56,7 +56,6 @@
   V(RecordWrite)                         \
   V(StoreBufferOverflow)                 \
   V(RegExpExec)                          \
-  V(TranscendentalCache)                 \
   V(Instanceof)                          \
   V(ConvertToDouble)                     \
   V(WriteInt32ToHeapNumber)              \
@@ -1177,10 +1176,6 @@
                              CompareIC::State* handler_state,
                              Token::Value* op);
 
-  static CompareIC::State CompareState(int minor_key) {
-    return static_cast<CompareIC::State>(HandlerStateField::decode(minor_key));
-  }
-
   virtual InlineCacheState GetICState();
 
  private:
diff --git a/src/codegen.h b/src/codegen.h
index 33672a2..b271d21 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -89,7 +89,6 @@
 // generated code both in runtime and compiled code.
 typedef double (*UnaryMathFunction)(double x);
 
-UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type);
 UnaryMathFunction CreateExpFunction();
 UnaryMathFunction CreateSqrtFunction();
 
diff --git a/src/compiler.cc b/src/compiler.cc
index c6dfa04..6b7786f 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -355,7 +355,6 @@
   }
   MODULE_NODE_LIST(DEF_VISIT)
   DECLARATION_NODE_LIST(DEF_VISIT)
-  AUXILIARY_NODE_LIST(DEF_VISIT)
 #undef DEF_VISIT
 };
 
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index ef39341..c36850c 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -380,7 +380,6 @@
       sampling_interval_(TimeDelta::FromMicroseconds(
           FLAG_cpu_profiler_sampling_interval)),
       profiles_(new CpuProfilesCollection(isolate->heap())),
-      next_profile_uid_(1),
       generator_(NULL),
       processor_(NULL),
       is_profiling_(false) {
@@ -395,7 +394,6 @@
       sampling_interval_(TimeDelta::FromMicroseconds(
           FLAG_cpu_profiler_sampling_interval)),
       profiles_(test_profiles),
-      next_profile_uid_(1),
       generator_(test_generator),
       processor_(test_processor),
       is_profiling_(false) {
@@ -421,7 +419,7 @@
 
 
 void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
-  if (profiles_->StartProfiling(title, next_profile_uid_++, record_samples)) {
+  if (profiles_->StartProfiling(title, record_samples)) {
     StartProcessorIfNotStarted();
   }
   processor_->AddCurrentStack(isolate_);
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index fcb9a67..53f00ff 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -268,7 +268,6 @@
   Isolate* isolate_;
   TimeDelta sampling_interval_;
   CpuProfilesCollection* profiles_;
-  unsigned next_profile_uid_;
   ProfileGenerator* generator_;
   ProfilerEventsProcessor* processor_;
   bool saved_is_logging_;
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index 25f79a4..c0485c6 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -723,19 +723,19 @@
 
 void Shell::AddOSMethods(Isolate* isolate, Handle<ObjectTemplate> os_templ) {
   os_templ->Set(String::NewFromUtf8(isolate, "system"),
-                FunctionTemplate::New(System));
+                FunctionTemplate::New(isolate, System));
   os_templ->Set(String::NewFromUtf8(isolate, "chdir"),
-                FunctionTemplate::New(ChangeDirectory));
+                FunctionTemplate::New(isolate, ChangeDirectory));
   os_templ->Set(String::NewFromUtf8(isolate, "setenv"),
-                FunctionTemplate::New(SetEnvironment));
+                FunctionTemplate::New(isolate, SetEnvironment));
   os_templ->Set(String::NewFromUtf8(isolate, "unsetenv"),
-                FunctionTemplate::New(UnsetEnvironment));
+                FunctionTemplate::New(isolate, UnsetEnvironment));
   os_templ->Set(String::NewFromUtf8(isolate, "umask"),
-                FunctionTemplate::New(SetUMask));
+                FunctionTemplate::New(isolate, SetUMask));
   os_templ->Set(String::NewFromUtf8(isolate, "mkdirp"),
-                FunctionTemplate::New(MakeDirectory));
+                FunctionTemplate::New(isolate, MakeDirectory));
   os_templ->Set(String::NewFromUtf8(isolate, "rmdir"),
-                FunctionTemplate::New(RemoveDirectory));
+                FunctionTemplate::New(isolate, RemoveDirectory));
 }
 
 }  // namespace v8
diff --git a/src/d8.cc b/src/d8.cc
index eb70f3e..00eca19 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -860,38 +860,38 @@
 Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
   Handle<ObjectTemplate> global_template = ObjectTemplate::New();
   global_template->Set(String::NewFromUtf8(isolate, "print"),
-                       FunctionTemplate::New(Print));
+                       FunctionTemplate::New(isolate, Print));
   global_template->Set(String::NewFromUtf8(isolate, "write"),
-                       FunctionTemplate::New(Write));
+                       FunctionTemplate::New(isolate, Write));
   global_template->Set(String::NewFromUtf8(isolate, "read"),
-                       FunctionTemplate::New(Read));
+                       FunctionTemplate::New(isolate, Read));
   global_template->Set(String::NewFromUtf8(isolate, "readbuffer"),
-                       FunctionTemplate::New(ReadBuffer));
+                       FunctionTemplate::New(isolate, ReadBuffer));
   global_template->Set(String::NewFromUtf8(isolate, "readline"),
-                       FunctionTemplate::New(ReadLine));
+                       FunctionTemplate::New(isolate, ReadLine));
   global_template->Set(String::NewFromUtf8(isolate, "load"),
-                       FunctionTemplate::New(Load));
+                       FunctionTemplate::New(isolate, Load));
   global_template->Set(String::NewFromUtf8(isolate, "quit"),
-                       FunctionTemplate::New(Quit));
+                       FunctionTemplate::New(isolate, Quit));
   global_template->Set(String::NewFromUtf8(isolate, "version"),
-                       FunctionTemplate::New(Version));
+                       FunctionTemplate::New(isolate, Version));
 
   // Bind the Realm object.
   Handle<ObjectTemplate> realm_template = ObjectTemplate::New();
   realm_template->Set(String::NewFromUtf8(isolate, "current"),
-                      FunctionTemplate::New(RealmCurrent));
+                      FunctionTemplate::New(isolate, RealmCurrent));
   realm_template->Set(String::NewFromUtf8(isolate, "owner"),
-                      FunctionTemplate::New(RealmOwner));
+                      FunctionTemplate::New(isolate, RealmOwner));
   realm_template->Set(String::NewFromUtf8(isolate, "global"),
-                      FunctionTemplate::New(RealmGlobal));
+                      FunctionTemplate::New(isolate, RealmGlobal));
   realm_template->Set(String::NewFromUtf8(isolate, "create"),
-                      FunctionTemplate::New(RealmCreate));
+                      FunctionTemplate::New(isolate, RealmCreate));
   realm_template->Set(String::NewFromUtf8(isolate, "dispose"),
-                      FunctionTemplate::New(RealmDispose));
+                      FunctionTemplate::New(isolate, RealmDispose));
   realm_template->Set(String::NewFromUtf8(isolate, "switch"),
-                      FunctionTemplate::New(RealmSwitch));
+                      FunctionTemplate::New(isolate, RealmSwitch));
   realm_template->Set(String::NewFromUtf8(isolate, "eval"),
-                      FunctionTemplate::New(RealmEval));
+                      FunctionTemplate::New(isolate, RealmEval));
   realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"),
                               RealmSharedGet, RealmSharedSet);
   global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template);
@@ -899,7 +899,7 @@
 #ifndef V8_SHARED
   Handle<ObjectTemplate> performance_template = ObjectTemplate::New();
   performance_template->Set(String::NewFromUtf8(isolate, "now"),
-                            FunctionTemplate::New(PerformanceNow));
+                            FunctionTemplate::New(isolate, PerformanceNow));
   global_template->Set(String::NewFromUtf8(isolate, "performance"),
                        performance_template);
 #endif  // V8_SHARED
diff --git a/src/debug.cc b/src/debug.cc
index 25be003..dbbfe7e 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -646,11 +646,10 @@
   // Globalize the script object, make it weak and use the location of the
   // global handle as the value in the hash map.
   Handle<Script> script_ =
-      Handle<Script>::cast(
-          (global_handles->Create(*script)));
-  global_handles->MakeWeak(reinterpret_cast<Object**>(script_.location()),
-                           this,
-                           ScriptCache::HandleWeakScript);
+      Handle<Script>::cast(global_handles->Create(*script));
+  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
+                          this,
+                          ScriptCache::HandleWeakScript);
   entry->value = script_.location();
 }
 
@@ -680,36 +679,37 @@
 
 
 void ScriptCache::Clear() {
-  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);
     Object** location = reinterpret_cast<Object**>(entry->value);
     ASSERT((*location)->IsScript());
-    global_handles->ClearWeakness(location);
-    global_handles->Destroy(location);
+    GlobalHandles::ClearWeakness(location);
+    GlobalHandles::Destroy(location);
   }
   // Clear the content of the hash map.
   HashMap::Clear();
 }
 
 
-void ScriptCache::HandleWeakScript(v8::Isolate* isolate,
-                                   v8::Persistent<v8::Value>* obj,
-                                   void* data) {
-  ScriptCache* script_cache = reinterpret_cast<ScriptCache*>(data);
-  // Find the location of the global handle.
-  Script** location =
-      reinterpret_cast<Script**>(Utils::OpenPersistent(*obj).location());
-  ASSERT((*location)->IsScript());
+void ScriptCache::HandleWeakScript(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  // Retrieve the script identifier.
+  Handle<Object> object = Utils::OpenHandle(*data.GetValue());
+  int id = Handle<Script>::cast(object)->id()->value();
+  void* key = reinterpret_cast<void*>(id);
+  uint32_t hash = Hash(id);
 
-  // Remove the entry from the cache.
-  int id = (*location)->id()->value();
-  script_cache->Remove(reinterpret_cast<void*>(id), Hash(id));
+  // Remove the corresponding entry from the cache.
+  ScriptCache* script_cache =
+      reinterpret_cast<ScriptCache*>(data.GetParameter());
+  HashMap::Entry* entry = script_cache->Lookup(key, hash, false);
+  Object** location = reinterpret_cast<Object**>(entry->value);
+  script_cache->Remove(key, hash);
   script_cache->collected_scripts_.Add(id);
 
   // Clear the weak handle.
-  obj->Reset();
+  GlobalHandles::Destroy(location);
 }
 
 
@@ -728,11 +728,11 @@
 }
 
 
-void Debug::HandleWeakDebugInfo(v8::Isolate* isolate,
-                                v8::Persistent<v8::Value>* obj,
-                                void* data) {
-  Debug* debug = reinterpret_cast<Isolate*>(isolate)->debug();
-  DebugInfoListNode* node = reinterpret_cast<DebugInfoListNode*>(data);
+void Debug::HandleWeakDebugInfo(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
+  DebugInfoListNode* node =
+      reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
   // We need to clear all breakpoints associated with the function to restore
   // original code and avoid patching the code twice later because
   // the function will live in the heap until next gc, and can be found by
@@ -741,29 +741,27 @@
   it.ClearAllDebugBreak();
   debug->RemoveDebugInfo(node->debug_info());
 #ifdef DEBUG
-  node = debug->debug_info_list_;
-  while (node != NULL) {
-    ASSERT(node != reinterpret_cast<DebugInfoListNode*>(data));
-    node = node->next();
+  for (DebugInfoListNode* n = debug->debug_info_list_;
+       n != NULL;
+       n = n->next()) {
+    ASSERT(n != node);
   }
 #endif
 }
 
 
 DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
-  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)));
-  global_handles->MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
-                           this,
-                           Debug::HandleWeakDebugInfo);
+  GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
+  debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
+  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
+                          this,
+                          Debug::HandleWeakDebugInfo);
 }
 
 
 DebugInfoListNode::~DebugInfoListNode() {
-  debug_info_->GetIsolate()->global_handles()->Destroy(
-      reinterpret_cast<Object**>(debug_info_.location()));
+  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
 }
 
 
@@ -921,8 +919,7 @@
   DestroyScriptCache();
 
   // Clear debugger context global handle.
-  isolate_->global_handles()->Destroy(
-      reinterpret_cast<Object**>(debug_context_.location()));
+  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
   debug_context_ = Handle<Context>();
 }
 
@@ -3249,12 +3246,12 @@
   // Clear the global handles for the event listener and the event listener data
   // object.
   if (!event_listener_.is_null()) {
-    global_handles->Destroy(
+    GlobalHandles::Destroy(
         reinterpret_cast<Object**>(event_listener_.location()));
     event_listener_ = Handle<Object>();
   }
   if (!event_listener_data_.is_null()) {
-    global_handles->Destroy(
+    GlobalHandles::Destroy(
         reinterpret_cast<Object**>(event_listener_data_.location()));
     event_listener_data_ = Handle<Object>();
   }
diff --git a/src/debug.h b/src/debug.h
index 8e71ea6..7eedfd2 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -201,9 +201,8 @@
   void Clear();
 
   // Weak handle callback for scripts in the cache.
-  static void HandleWeakScript(v8::Isolate* isolate,
-                               v8::Persistent<v8::Value>* obj,
-                               void* data);
+  static void HandleWeakScript(
+      const v8::WeakCallbackData<v8::Value, void>& data);
 
   Isolate* isolate_;
   // List used during GC to temporarily store id's of collected scripts.
@@ -403,9 +402,8 @@
   static const int kEstimatedNofBreakPointsInFunction = 16;
 
   // Passed to MakeWeak.
-  static void HandleWeakDebugInfo(v8::Isolate* isolate,
-                                  v8::Persistent<v8::Value>* obj,
-                                  void* data);
+  static void HandleWeakDebugInfo(
+      const v8::WeakCallbackData<v8::Value, void>& data);
 
   friend class Debugger;
   friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
index edc7dd8..7dc7a3c 100644
--- a/src/extensions/externalize-string-extension.cc
+++ b/src/extensions/externalize-string-extension.cc
@@ -64,10 +64,12 @@
 ExternalizeStringExtension::GetNativeFunctionTemplate(
     v8::Isolate* isolate, v8::Handle<v8::String> str) {
   if (strcmp(*v8::String::Utf8Value(str), "externalizeString") == 0) {
-    return v8::FunctionTemplate::New(ExternalizeStringExtension::Externalize);
+    return v8::FunctionTemplate::New(isolate,
+                                     ExternalizeStringExtension::Externalize);
   } else {
     ASSERT(strcmp(*v8::String::Utf8Value(str), "isAsciiString") == 0);
-    return v8::FunctionTemplate::New(ExternalizeStringExtension::IsAscii);
+    return v8::FunctionTemplate::New(isolate,
+                                     ExternalizeStringExtension::IsAscii);
   }
 }
 
diff --git a/src/extensions/free-buffer-extension.cc b/src/extensions/free-buffer-extension.cc
index 5cf2b68..c2e3102 100644
--- a/src/extensions/free-buffer-extension.cc
+++ b/src/extensions/free-buffer-extension.cc
@@ -36,7 +36,7 @@
 v8::Handle<v8::FunctionTemplate> FreeBufferExtension::GetNativeFunctionTemplate(
     v8::Isolate* isolate,
     v8::Handle<v8::String> str) {
-  return v8::FunctionTemplate::New(FreeBufferExtension::FreeBuffer);
+  return v8::FunctionTemplate::New(isolate, FreeBufferExtension::FreeBuffer);
 }
 
 
diff --git a/src/extensions/gc-extension.cc b/src/extensions/gc-extension.cc
index b8442c1..69fd717 100644
--- a/src/extensions/gc-extension.cc
+++ b/src/extensions/gc-extension.cc
@@ -35,7 +35,7 @@
 v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunctionTemplate(
     v8::Isolate* isolate,
     v8::Handle<v8::String> str) {
-  return v8::FunctionTemplate::New(GCExtension::GC);
+  return v8::FunctionTemplate::New(isolate, GCExtension::GC);
 }
 
 
diff --git a/src/extensions/statistics-extension.cc b/src/extensions/statistics-extension.cc
index 92d152d..767c9e7 100644
--- a/src/extensions/statistics-extension.cc
+++ b/src/extensions/statistics-extension.cc
@@ -38,7 +38,7 @@
     v8::Isolate* isolate,
     v8::Handle<v8::String> str) {
   ASSERT(strcmp(*v8::String::Utf8Value(str), "getV8Statistics") == 0);
-  return v8::FunctionTemplate::New(StatisticsExtension::GetCounters);
+  return v8::FunctionTemplate::New(isolate, StatisticsExtension::GetCounters);
 }
 
 
diff --git a/src/extensions/trigger-failure-extension.cc b/src/extensions/trigger-failure-extension.cc
index 5fe6bbb..68dea93 100644
--- a/src/extensions/trigger-failure-extension.cc
+++ b/src/extensions/trigger-failure-extension.cc
@@ -44,13 +44,16 @@
     v8::Handle<v8::String> str) {
   if (strcmp(*v8::String::Utf8Value(str), "triggerCheckFalse") == 0) {
     return v8::FunctionTemplate::New(
+        isolate,
         TriggerFailureExtension::TriggerCheckFalse);
   } else if (strcmp(*v8::String::Utf8Value(str), "triggerAssertFalse") == 0) {
     return v8::FunctionTemplate::New(
+        isolate,
         TriggerFailureExtension::TriggerAssertFalse);
   } else {
     CHECK_EQ(0, strcmp(*v8::String::Utf8Value(str), "triggerSlowAssertFalse"));
     return v8::FunctionTemplate::New(
+        isolate,
         TriggerFailureExtension::TriggerSlowAssertFalse);
   }
 }
diff --git a/src/global-handles.cc b/src/global-handles.cc
index 2ebe1c0..0944979 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -169,13 +169,6 @@
     flags_ = IsInNewSpaceList::update(flags_, v);
   }
 
-  bool is_revivable_callback() {
-    return IsRevivableCallback::decode(flags_);
-  }
-  void set_revivable_callback(bool v) {
-    flags_ = IsRevivableCallback::update(flags_, v);
-  }
-
   bool IsNearDeath() const {
     // Check for PENDING to ensure correct answer when processing callbacks.
     return state() == PENDING || state() == NEAR_DEATH;
@@ -234,21 +227,12 @@
     parameter_or_next_free_.next_free = value;
   }
 
-  void MakeWeak(void* parameter,
-                WeakCallback weak_callback,
-                RevivableCallback revivable_callback) {
-    ASSERT((weak_callback == NULL) != (revivable_callback == NULL));
+  void MakeWeak(void* parameter, WeakCallback weak_callback) {
+    ASSERT(weak_callback != NULL);
     ASSERT(state() != FREE);
     set_state(WEAK);
     set_parameter(parameter);
-    if (weak_callback != NULL) {
-      weak_callback_ = weak_callback;
-      set_revivable_callback(false);
-    } else {
-      weak_callback_ =
-          reinterpret_cast<WeakCallback>(revivable_callback);
-      set_revivable_callback(true);
-    }
+    weak_callback_ = weak_callback;
   }
 
   void ClearWeakness() {
@@ -278,20 +262,12 @@
       // Leaving V8.
       VMState<EXTERNAL> state(isolate);
       HandleScope handle_scope(isolate);
-      if (is_revivable_callback()) {
-        RevivableCallback revivable =
-            reinterpret_cast<RevivableCallback>(weak_callback_);
-        revivable(reinterpret_cast<v8::Isolate*>(isolate),
-                  reinterpret_cast<Persistent<Value>*>(&object),
-                  par);
-      } else {
-        Handle<Object> handle(*object, isolate);
-        v8::WeakCallbackData<v8::Value, void> data(
-            reinterpret_cast<v8::Isolate*>(isolate),
-            v8::Utils::ToLocal(handle),
-            par);
-        weak_callback_(data);
-      }
+      Handle<Object> handle(*object, isolate);
+      v8::WeakCallbackData<v8::Value, void> data(
+          reinterpret_cast<v8::Isolate*>(isolate),
+          v8::Utils::ToLocal(handle),
+          par);
+      weak_callback_(data);
     }
     // Absence of explicit cleanup or revival of weak handle
     // in most of the cases would lead to memory leak.
@@ -325,7 +301,6 @@
   class IsIndependent:        public BitField<bool,  4, 1> {};
   class IsPartiallyDependent: public BitField<bool,  5, 1> {};
   class IsInNewSpaceList:     public BitField<bool,  6, 1> {};
-  class IsRevivableCallback:  public BitField<bool,  7, 1> {};
 
   uint8_t flags_;
 
@@ -522,10 +497,8 @@
 
 void GlobalHandles::MakeWeak(Object** location,
                              void* parameter,
-                             WeakCallback weak_callback,
-                             RevivableCallback revivable_callback) {
-  Node::FromLocation(location)->MakeWeak(
-      parameter, weak_callback, revivable_callback);
+                             WeakCallback weak_callback) {
+  Node::FromLocation(location)->MakeWeak(parameter, weak_callback);
 }
 
 
diff --git a/src/global-handles.h b/src/global-handles.h
index 4b46aac..a406451 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -135,7 +135,6 @@
   static void Destroy(Object** location);
 
   typedef WeakCallbackData<v8::Value, void>::Callback WeakCallback;
-  typedef WeakReferenceCallbacks<v8::Value, void>::Revivable RevivableCallback;
 
   // Make the global handle weak and set the callback parameter for the
   // handle.  When the garbage collector recognizes that only weak global
@@ -145,14 +144,7 @@
   // reason is that Smi::FromInt(0) does not change during garage collection.
   static void MakeWeak(Object** location,
                        void* parameter,
-                       WeakCallback weak_callback,
-                       RevivableCallback revivable_callback);
-
-  static inline void MakeWeak(Object** location,
-                              void* parameter,
-                              RevivableCallback revivable_callback) {
-    MakeWeak(location, parameter, NULL, revivable_callback);
-  }
+                       WeakCallback weak_callback);
 
   void RecordStats(HeapStats* stats);
 
diff --git a/src/handles.cc b/src/handles.cc
index 2d41402..8bf3b0c 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -225,17 +225,15 @@
 // collector will call the weak callback on the global handle
 // associated with the wrapper and get rid of both the wrapper and the
 // handle.
-static void ClearWrapperCache(v8::Isolate* v8_isolate,
-                              Persistent<v8::Value>* handle,
-                              void*) {
-  Handle<Object> cache = Utils::OpenPersistent(handle);
-  JSValue* wrapper = JSValue::cast(*cache);
+static void ClearWrapperCache(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  Object** location = reinterpret_cast<Object**>(data.GetParameter());
+  JSValue* wrapper = JSValue::cast(*location);
   Foreign* foreign = Script::cast(wrapper->value())->wrapper();
-  ASSERT(foreign->foreign_address() ==
-         reinterpret_cast<Address>(cache.location()));
+  ASSERT_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
   foreign->set_foreign_address(0);
-  Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
-  isolate->global_handles()->Destroy(cache.location());
+  GlobalHandles::Destroy(location);
+  Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
   isolate->counters()->script_wrappers()->Decrement();
 }
 
@@ -267,9 +265,9 @@
   // for future use. The cache will automatically be cleared by the
   // garbage collector when it is not used anymore.
   Handle<Object> handle = isolate->global_handles()->Create(*result);
-  isolate->global_handles()->MakeWeak(handle.location(),
-                                      NULL,
-                                      &ClearWrapperCache);
+  GlobalHandles::MakeWeak(handle.location(),
+                          reinterpret_cast<void*>(handle.location()),
+                          &ClearWrapperCache);
   script->wrapper()->set_foreign_address(
       reinterpret_cast<Address>(handle.location()));
   return result;
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 3229aee..11783b3 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -747,56 +747,6 @@
 }
 
 
-MaybeObject* TranscendentalCache::Get(Type type, double input) {
-  SubCache* cache = caches_[type];
-  if (cache == NULL) {
-    caches_[type] = cache = new SubCache(isolate_, type);
-  }
-  return cache->Get(input);
-}
-
-
-Address TranscendentalCache::cache_array_address() {
-  return reinterpret_cast<Address>(caches_);
-}
-
-
-double TranscendentalCache::SubCache::Calculate(double input) {
-  switch (type_) {
-    case LOG:
-      return fast_log(input);
-    default:
-      UNREACHABLE();
-      return 0.0;  // Never happens.
-  }
-}
-
-
-MaybeObject* TranscendentalCache::SubCache::Get(double input) {
-  Converter c;
-  c.dbl = input;
-  int hash = Hash(c);
-  Element e = elements_[hash];
-  if (e.in[0] == c.integers[0] &&
-      e.in[1] == c.integers[1]) {
-    ASSERT(e.output != NULL);
-    isolate_->counters()->transcendental_cache_hit()->Increment();
-    return e.output;
-  }
-  double answer = Calculate(input);
-  isolate_->counters()->transcendental_cache_miss()->Increment();
-  Object* heap_number;
-  { MaybeObject* maybe_heap_number =
-        isolate_->heap()->AllocateHeapNumber(answer);
-    if (!maybe_heap_number->ToObject(&heap_number)) return maybe_heap_number;
-  }
-  elements_[hash].in[0] = c.integers[0];
-  elements_[hash].in[1] = c.integers[1];
-  elements_[hash].output = heap_number;
-  return heap_number;
-}
-
-
 AlwaysAllocateScope::AlwaysAllocateScope() {
   // We shouldn't hit any nested scopes, because that requires
   // non-handle code to call handle code. The code still works but
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index 1e40950..7413b6e 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -212,4 +212,10 @@
 }
 
 
+void HeapProfiler::ClearHeapObjectMap() {
+  ids_.Reset(new HeapObjectsMap(heap()));
+  if (!is_tracking_allocations()) is_tracking_object_moves_ = false;
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/heap-profiler.h b/src/heap-profiler.h
index 6d15868..e4838df 100644
--- a/src/heap-profiler.h
+++ b/src/heap-profiler.h
@@ -87,6 +87,7 @@
   }
 
   Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id);
+  void ClearHeapObjectMap();
 
  private:
   Heap* heap() const { return ids_->heap(); }
diff --git a/src/heap.cc b/src/heap.cc
index 6921bb6..f6c6ae6 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -436,7 +436,6 @@
 
 void Heap::GarbageCollectionPrologue() {
   {  AllowHeapAllocation for_the_first_part_of_prologue;
-    isolate_->transcendental_cache()->Clear();
     ClearJSFunctionResultCaches();
     gc_count_++;
     unflattened_strings_length_ = 0;
@@ -7755,29 +7754,6 @@
 #endif
 
 
-TranscendentalCache::SubCache::SubCache(Isolate* isolate, Type t)
-  : type_(t),
-    isolate_(isolate) {
-  uint32_t in0 = 0xffffffffu;  // Bit-pattern for a NaN that isn't
-  uint32_t in1 = 0xffffffffu;  // generated by the FPU.
-  for (int i = 0; i < kCacheSize; i++) {
-    elements_[i].in[0] = in0;
-    elements_[i].in[1] = in1;
-    elements_[i].output = NULL;
-  }
-}
-
-
-void TranscendentalCache::Clear() {
-  for (int i = 0; i < kNumberOfCaches; i++) {
-    if (caches_[i] != NULL) {
-      delete caches_[i];
-      caches_[i] = NULL;
-    }
-  }
-}
-
-
 void ExternalStringTable::CleanUp() {
   int last = 0;
   for (int i = 0; i < new_space_strings_.length(); ++i) {
diff --git a/src/heap.h b/src/heap.h
index d2d6961..871c4d8 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2894,85 +2894,6 @@
 };
 
 
-class TranscendentalCache {
- public:
-  enum Type { LOG, kNumberOfCaches};
-  static const int kTranscendentalTypeBits = 3;
-  STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches);
-
-  // Returns a heap number with f(input), where f is a math function specified
-  // by the 'type' argument.
-  MUST_USE_RESULT inline MaybeObject* Get(Type type, double input);
-
-  // The cache contains raw Object pointers.  This method disposes of
-  // them before a garbage collection.
-  void Clear();
-
- private:
-  class SubCache {
-    static const int kCacheSize = 512;
-
-    explicit SubCache(Isolate* isolate, Type t);
-
-    MUST_USE_RESULT inline MaybeObject* Get(double input);
-
-    inline double Calculate(double input);
-
-    struct Element {
-      uint32_t in[2];
-      Object* output;
-    };
-
-    union Converter {
-      double dbl;
-      uint32_t integers[2];
-    };
-
-    inline static int Hash(const Converter& c) {
-      uint32_t hash = (c.integers[0] ^ c.integers[1]);
-      hash ^= static_cast<int32_t>(hash) >> 16;
-      hash ^= static_cast<int32_t>(hash) >> 8;
-      return (hash & (kCacheSize - 1));
-    }
-
-    Element elements_[kCacheSize];
-    Type type_;
-    Isolate* isolate_;
-
-    // Allow access to the caches_ array as an ExternalReference.
-    friend class ExternalReference;
-    // Inline implementation of the cache.
-    friend class TranscendentalCacheStub;
-    // For evaluating value.
-    friend class TranscendentalCache;
-
-    DISALLOW_COPY_AND_ASSIGN(SubCache);
-  };
-
-  explicit TranscendentalCache(Isolate* isolate) : isolate_(isolate) {
-    for (int i = 0; i < kNumberOfCaches; ++i) caches_[i] = NULL;
-  }
-
-  ~TranscendentalCache() {
-    for (int i = 0; i < kNumberOfCaches; ++i) delete caches_[i];
-  }
-
-  // Used to create an external reference.
-  inline Address cache_array_address();
-
-  // Instantiation
-  friend class Isolate;
-  // Inline implementation of the caching.
-  friend class TranscendentalCacheStub;
-  // Allow access to the caches_ array as an ExternalReference.
-  friend class ExternalReference;
-
-  Isolate* isolate_;
-  SubCache* caches_[kNumberOfCaches];
-  DISALLOW_COPY_AND_ASSIGN(TranscendentalCache);
-};
-
-
 // Abstract base class for checking whether a weak object should be retained.
 class WeakObjectRetainer {
  public:
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index e7ad219..43235c2 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -3495,11 +3495,18 @@
   dominator_allocate->clear_next_map_word_ = clear_next_map_word_;
 
   // After that replace the dominated allocate instruction.
+  HInstruction* inner_offset = HConstant::CreateAndInsertBefore(
+      zone,
+      context(),
+      dominator_size_constant,
+      Representation::None(),
+      this);
+
   HInstruction* dominated_allocate_instr =
       HInnerAllocatedObject::New(zone,
                                  context(),
                                  dominator_allocate,
-                                 dominator_size,
+                                 inner_offset,
                                  type());
   dominated_allocate_instr->InsertBefore(this);
   DeleteAndReplaceWith(dominated_allocate_instr);
@@ -3873,7 +3880,7 @@
       case kMathExp:
         return H_CONSTANT_DOUBLE(fast_exp(d));
       case kMathLog:
-        return H_CONSTANT_DOUBLE(fast_log(d));
+        return H_CONSTANT_DOUBLE(log(d));
       case kMathSqrt:
         return H_CONSTANT_DOUBLE(fast_sqrt(d));
       case kMathPowHalf:
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 4dd24fd..df8d2dc 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2682,10 +2682,6 @@
         SetGVNFlag(kChangesNewSpacePromotion);
         break;
       case kMathLog:
-        set_representation(Representation::Double());
-        // These operations use the TranscendentalCache, so they may allocate.
-        SetGVNFlag(kChangesNewSpacePromotion);
-        break;
       case kMathExp:
       case kMathSqrt:
       case kMathPowHalf:
@@ -5287,13 +5283,6 @@
 
   HValue* context() { return value(); }
 
-  void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
-    transcendental_type_ = transcendental_type;
-  }
-  TranscendentalCache::Type transcendental_type() {
-    return transcendental_type_;
-  }
-
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub)
@@ -5301,12 +5290,10 @@
  private:
   HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
       : HUnaryCall(context, argument_count),
-        major_key_(major_key),
-        transcendental_type_(TranscendentalCache::kNumberOfCaches) {
+        major_key_(major_key) {
   }
 
   CodeStub::Major major_key_;
-  TranscendentalCache::Type transcendental_type_;
 };
 
 
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 176dd9f..b3549f5 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4136,45 +4136,27 @@
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
 
-  // We only optimize switch statements with smi-literal smi comparisons,
-  // with a bounded number of clauses.
+  // We only optimize switch statements with a bounded number of clauses.
   const int kCaseClauseLimit = 128;
   ZoneList<CaseClause*>* clauses = stmt->cases();
   int clause_count = clauses->length();
+  ZoneList<HBasicBlock*> body_blocks(clause_count, zone());
   if (clause_count > kCaseClauseLimit) {
     return Bailout(kSwitchStatementTooManyClauses);
   }
 
-  ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
-  if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
-    return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels);
-  }
-
   CHECK_ALIVE(VisitForValue(stmt->tag()));
   Add<HSimulate>(stmt->EntryId());
-  HValue* tag_value = Pop();
-  HBasicBlock* first_test_block = current_block();
-
-  HUnaryControlInstruction* string_check = NULL;
-  HBasicBlock* not_string_block = NULL;
-
-  // Test switch's tag value if all clauses are string literals
-  if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
-    first_test_block = graph()->CreateBasicBlock();
-    not_string_block = graph()->CreateBasicBlock();
-    string_check = New<HIsStringAndBranch>(
-        tag_value, first_test_block, not_string_block);
-    FinishCurrentBlock(string_check);
-
-    set_current_block(first_test_block);
-  }
+  HValue* tag_value = Top();
+  Handle<Type> tag_type = stmt->tag()->bounds().lower;
 
   // 1. Build all the tests, with dangling true branches
   BailoutId default_id = BailoutId::None();
   for (int i = 0; i < clause_count; ++i) {
     CaseClause* clause = clauses->at(i);
     if (clause->is_default()) {
-      default_id = clause->EntryId();
+      body_blocks.Add(NULL, zone());
+      if (default_id.IsNone()) default_id = clause->EntryId();
       continue;
     }
 
@@ -4182,48 +4164,33 @@
     CHECK_ALIVE(VisitForValue(clause->label()));
     HValue* label_value = Pop();
 
+    Handle<Type> label_type = clause->label()->bounds().lower;
+    Handle<Type> combined_type = clause->compare_type();
+    HControlInstruction* compare = BuildCompareInstruction(
+        Token::EQ_STRICT, tag_value, label_value, tag_type, label_type,
+        combined_type, stmt->tag()->position(), clause->label()->position(),
+        clause->id());
+
     HBasicBlock* next_test_block = graph()->CreateBasicBlock();
     HBasicBlock* body_block = graph()->CreateBasicBlock();
-
-    HControlInstruction* compare;
-
-    if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
-      if (!clause->compare_type()->Is(Type::Smi())) {
-        Add<HDeoptimize>("Non-smi switch type", Deoptimizer::SOFT);
-      }
-
-      HCompareNumericAndBranch* compare_ =
-          New<HCompareNumericAndBranch>(tag_value,
-                                        label_value,
-                                        Token::EQ_STRICT);
-      compare_->set_observed_input_representation(
-          Representation::Smi(), Representation::Smi());
-      compare = compare_;
-    } else {
-      compare = New<HStringCompareAndBranch>(tag_value,
-                                             label_value,
-                                             Token::EQ_STRICT);
-    }
-
+    body_blocks.Add(body_block, zone());
     compare->SetSuccessorAt(0, body_block);
     compare->SetSuccessorAt(1, next_test_block);
     FinishCurrentBlock(compare);
 
+    set_current_block(body_block);
+    Drop(1);  // tag_value
+
     set_current_block(next_test_block);
   }
 
   // Save the current block to use for the default or to join with the
   // exit.
   HBasicBlock* last_block = current_block();
-
-  if (not_string_block != NULL) {
-    BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId();
-    last_block = CreateJoin(last_block, not_string_block, join_id);
-  }
+  Drop(1);  // tag_value
 
   // 2. Loop over the clauses and the linked list of tests in lockstep,
   // translating the clause bodies.
-  HBasicBlock* curr_test_block = first_test_block;
   HBasicBlock* fall_through_block = NULL;
 
   BreakAndContinueInfo break_info(stmt);
@@ -4235,40 +4202,16 @@
       // goes to.
       HBasicBlock* normal_block = NULL;
       if (clause->is_default()) {
-        if (last_block != NULL) {
-          normal_block = last_block;
-          last_block = NULL;  // Cleared to indicate we've handled it.
-        }
+        if (last_block == NULL) continue;
+        normal_block = last_block;
+        last_block = NULL;  // Cleared to indicate we've handled it.
       } else {
-        // If the current test block is deoptimizing due to an unhandled clause
-        // of the switch, the test instruction is in the next block since the
-        // deopt must end the current block.
-        if (curr_test_block->IsDeoptimizing()) {
-          ASSERT(curr_test_block->end()->SecondSuccessor() == NULL);
-          curr_test_block = curr_test_block->end()->FirstSuccessor();
-        }
-        normal_block = curr_test_block->end()->FirstSuccessor();
-        curr_test_block = curr_test_block->end()->SecondSuccessor();
+        normal_block = body_blocks[i];
       }
 
-      // Identify a block to emit the body into.
-      if (normal_block == NULL) {
-        if (fall_through_block == NULL) {
-          // (a) Unreachable.
-          if (clause->is_default()) {
-            continue;  // Might still be reachable clause bodies.
-          } else {
-            break;
-          }
-        } else {
-          // (b) Reachable only as fall through.
-          set_current_block(fall_through_block);
-        }
-      } else if (fall_through_block == NULL) {
-        // (c) Reachable only normally.
+      if (fall_through_block == NULL) {
         set_current_block(normal_block);
       } else {
-        // (d) Reachable both ways.
         HBasicBlock* join = CreateJoin(fall_through_block,
                                        normal_block,
                                        clause->EntryId());
@@ -9152,9 +9095,6 @@
   Handle<Type> left_type = expr->left()->bounds().lower;
   Handle<Type> right_type = expr->right()->bounds().lower;
   Handle<Type> combined_type = expr->combined_type();
-  Representation combined_rep = Representation::FromType(combined_type);
-  Representation left_rep = Representation::FromType(left_type);
-  Representation right_rep = Representation::FromType(right_type);
 
   CHECK_ALIVE(VisitForValue(expr->left()));
   CHECK_ALIVE(VisitForValue(expr->right()));
@@ -9228,34 +9168,54 @@
     combined_type = left_type = right_type = handle(Type::Any(), isolate());
   }
 
+  HControlInstruction* compare = BuildCompareInstruction(
+      op, left, right, left_type, right_type, combined_type,
+      expr->left()->position(), expr->right()->position(), expr->id());
+  if (compare == NULL) return;  // Bailed out.
+  return ast_context()->ReturnControl(compare, expr->id());
+}
+
+
+HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
+    Token::Value op,
+    HValue* left,
+    HValue* right,
+    Handle<Type> left_type,
+    Handle<Type> right_type,
+    Handle<Type> combined_type,
+    int left_position,
+    int right_position,
+    BailoutId bailout_id) {
+  Representation left_rep = Representation::FromType(left_type);
+  Representation right_rep = Representation::FromType(right_type);
+  Representation combined_rep = Representation::FromType(combined_type);
+
   if (combined_type->Is(Type::Receiver())) {
-    switch (op) {
-      case Token::EQ:
-      case Token::EQ_STRICT: {
-        // Can we get away with map check and not instance type check?
-        if (combined_type->IsClass()) {
-          Handle<Map> map = combined_type->AsClass();
-          AddCheckMap(left, map);
-          AddCheckMap(right, map);
-          HCompareObjectEqAndBranch* result =
-              New<HCompareObjectEqAndBranch>(left, right);
-          if (FLAG_emit_opt_code_positions) {
-            result->set_operand_position(zone(), 0, expr->left()->position());
-            result->set_operand_position(zone(), 1, expr->right()->position());
-          }
-          return ast_context()->ReturnControl(result, expr->id());
-        } else {
-          BuildCheckHeapObject(left);
-          Add<HCheckInstanceType>(left, HCheckInstanceType::IS_SPEC_OBJECT);
-          BuildCheckHeapObject(right);
-          Add<HCheckInstanceType>(right, HCheckInstanceType::IS_SPEC_OBJECT);
-          HCompareObjectEqAndBranch* result =
-              New<HCompareObjectEqAndBranch>(left, right);
-          return ast_context()->ReturnControl(result, expr->id());
+    if (Token::IsEqualityOp(op)) {
+      // Can we get away with map check and not instance type check?
+      if (combined_type->IsClass()) {
+        Handle<Map> map = combined_type->AsClass();
+        AddCheckMap(left, map);
+        AddCheckMap(right, map);
+        HCompareObjectEqAndBranch* result =
+            New<HCompareObjectEqAndBranch>(left, right);
+        if (FLAG_emit_opt_code_positions) {
+          result->set_operand_position(zone(), 0, left_position);
+          result->set_operand_position(zone(), 1, right_position);
         }
+        return result;
+      } else {
+        BuildCheckHeapObject(left);
+        Add<HCheckInstanceType>(left, HCheckInstanceType::IS_SPEC_OBJECT);
+        BuildCheckHeapObject(right);
+        Add<HCheckInstanceType>(right, HCheckInstanceType::IS_SPEC_OBJECT);
+        HCompareObjectEqAndBranch* result =
+            New<HCompareObjectEqAndBranch>(left, right);
+        return result;
       }
-      default:
-        return Bailout(kUnsupportedNonPrimitiveCompare);
+    } else {
+      Bailout(kUnsupportedNonPrimitiveCompare);
+      return NULL;
     }
   } else if (combined_type->Is(Type::InternalizedString()) &&
              Token::IsEqualityOp(op)) {
@@ -9265,7 +9225,7 @@
     Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING);
     HCompareObjectEqAndBranch* result =
         New<HCompareObjectEqAndBranch>(left, right);
-    return ast_context()->ReturnControl(result, expr->id());
+    return result;
   } else if (combined_type->Is(Type::String())) {
     BuildCheckHeapObject(left);
     Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING);
@@ -9273,23 +9233,28 @@
     Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING);
     HStringCompareAndBranch* result =
         New<HStringCompareAndBranch>(left, right, op);
-    return ast_context()->ReturnControl(result, expr->id());
+    return result;
   } else {
     if (combined_rep.IsTagged() || combined_rep.IsNone()) {
-      HCompareGeneric* result = New<HCompareGeneric>(left, right, op);
+      HCompareGeneric* result = Add<HCompareGeneric>(left, right, op);
       result->set_observed_input_representation(1, left_rep);
       result->set_observed_input_representation(2, right_rep);
-      return ast_context()->ReturnInstruction(result, expr->id());
+      if (result->HasObservableSideEffects()) {
+        Push(result);
+        AddSimulate(bailout_id, REMOVABLE_SIMULATE);
+        Drop(1);
+      }
+      // TODO(jkummerow): Can we make this more efficient?
+      HBranch* branch = New<HBranch>(result);
+      return branch;
     } else {
       HCompareNumericAndBranch* result =
           New<HCompareNumericAndBranch>(left, right, op);
       result->set_observed_input_representation(left_rep, right_rep);
       if (FLAG_emit_opt_code_positions) {
-        result->SetOperandPositions(zone(),
-                                    expr->left()->position(),
-                                    expr->right()->position());
+        result->SetOperandPositions(zone(), left_position, right_position);
       }
-      return ast_context()->ReturnControl(result, expr->id());
+      return result;
     }
   }
 }
@@ -10146,11 +10111,10 @@
 
 
 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
-  ASSERT_EQ(1, call->arguments()->length());
-  CHECK_ALIVE(VisitArgumentList(call->arguments()));
-  HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
-  result->set_transcendental_type(TranscendentalCache::LOG);
-  Drop(1);
+  ASSERT(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* value = Pop();
+  HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathLog);
   return ast_context()->ReturnInstruction(result, call->id());
 }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 61e98b2..b2fd14c 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -2323,6 +2323,15 @@
   void HandleLiteralCompareNil(CompareOperation* expr,
                                Expression* sub_expr,
                                NilValue nil);
+  HControlInstruction* BuildCompareInstruction(Token::Value op,
+                                               HValue* left,
+                                               HValue* right,
+                                               Handle<Type> left_type,
+                                               Handle<Type> right_type,
+                                               Handle<Type> combined_type,
+                                               int left_position,
+                                               int right_position,
+                                               BailoutId bailout_id);
 
   HInstruction* BuildStringCharCodeAt(HValue* string,
                                       HValue* index);
diff --git a/src/i18n.cc b/src/i18n.cc
index 80a739c..f340cc0 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -864,15 +864,24 @@
 }
 
 
-void DateFormat::DeleteDateFormat(v8::Isolate* isolate,
-                                  Persistent<v8::Value>* object,
-                                  void* param) {
-  // First delete the hidden C++ object.
-  delete reinterpret_cast<icu::SimpleDateFormat*>(Handle<JSObject>::cast(
-      v8::Utils::OpenPersistent(object))->GetInternalField(0));
+template<class T>
+void DeleteNativeObjectAt(const v8::WeakCallbackData<v8::Value, void>& data,
+                          int index) {
+  v8::Local<v8::Object> obj = v8::Handle<v8::Object>::Cast(data.GetValue());
+  delete reinterpret_cast<T*>(obj->GetAlignedPointerFromInternalField(index));
+}
 
-  // Then dispose of the persistent handle to JS object.
-  object->Reset();
+
+static void DestroyGlobalHandle(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter()));
+}
+
+
+void DateFormat::DeleteDateFormat(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  DeleteNativeObjectAt<icu::SimpleDateFormat>(data, 0);
+  DestroyGlobalHandle(data);
 }
 
 
@@ -928,15 +937,10 @@
 }
 
 
-void NumberFormat::DeleteNumberFormat(v8::Isolate* isolate,
-                                      Persistent<v8::Value>* object,
-                                      void* param) {
-  // First delete the hidden C++ object.
-  delete reinterpret_cast<icu::DecimalFormat*>(Handle<JSObject>::cast(
-      v8::Utils::OpenPersistent(object))->GetInternalField(0));
-
-  // Then dispose of the persistent handle to JS object.
-  object->Reset();
+void NumberFormat::DeleteNumberFormat(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  DeleteNativeObjectAt<icu::DecimalFormat>(data, 0);
+  DestroyGlobalHandle(data);
 }
 
 
@@ -989,15 +993,10 @@
 }
 
 
-void Collator::DeleteCollator(v8::Isolate* isolate,
-                              Persistent<v8::Value>* object,
-                              void* param) {
-  // First delete the hidden C++ object.
-  delete reinterpret_cast<icu::Collator*>(Handle<JSObject>::cast(
-      v8::Utils::OpenPersistent(object))->GetInternalField(0));
-
-  // Then dispose of the persistent handle to JS object.
-  object->Reset();
+void Collator::DeleteCollator(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  DeleteNativeObjectAt<icu::Collator>(data, 0);
+  DestroyGlobalHandle(data);
 }
 
 
@@ -1053,18 +1052,11 @@
 }
 
 
-void BreakIterator::DeleteBreakIterator(v8::Isolate* isolate,
-                                        Persistent<v8::Value>* object,
-                                        void* param) {
-  // First delete the hidden C++ object.
-  delete reinterpret_cast<icu::BreakIterator*>(Handle<JSObject>::cast(
-      v8::Utils::OpenPersistent(object))->GetInternalField(0));
-
-  delete reinterpret_cast<icu::UnicodeString*>(Handle<JSObject>::cast(
-      v8::Utils::OpenPersistent(object))->GetInternalField(1));
-
-  // Then dispose of the persistent handle to JS object.
-  object->Reset();
+void BreakIterator::DeleteBreakIterator(
+    const v8::WeakCallbackData<v8::Value, void>& data) {
+  DeleteNativeObjectAt<icu::BreakIterator>(data, 0);
+  DeleteNativeObjectAt<icu::UnicodeString>(data, 1);
+  DestroyGlobalHandle(data);
 }
 
 } }  // namespace v8::internal
diff --git a/src/i18n.h b/src/i18n.h
index 08e7f2b..50beb49 100644
--- a/src/i18n.h
+++ b/src/i18n.h
@@ -71,9 +71,9 @@
 
   // Release memory we allocated for the DateFormat once the JS object that
   // holds the pointer gets garbage collected.
-  static void DeleteDateFormat(v8::Isolate* isolate,
-                               Persistent<v8::Value>* object,
-                               void* param);
+  static void DeleteDateFormat(
+      const v8::WeakCallbackData<v8::Value, void>& data);
+
  private:
   DateFormat();
 };
@@ -95,9 +95,9 @@
 
   // Release memory we allocated for the NumberFormat once the JS object that
   // holds the pointer gets garbage collected.
-  static void DeleteNumberFormat(v8::Isolate* isolate,
-                                 Persistent<v8::Value>* object,
-                                 void* param);
+  static void DeleteNumberFormat(
+      const v8::WeakCallbackData<v8::Value, void>& data);
+
  private:
   NumberFormat();
 };
@@ -118,9 +118,9 @@
 
   // Release memory we allocated for the Collator once the JS object that holds
   // the pointer gets garbage collected.
-  static void DeleteCollator(v8::Isolate* isolate,
-                             Persistent<v8::Value>* object,
-                             void* param);
+  static void DeleteCollator(
+      const v8::WeakCallbackData<v8::Value, void>& data);
+
  private:
   Collator();
 };
@@ -141,9 +141,8 @@
 
   // Release memory we allocated for the BreakIterator once the JS object that
   // holds the pointer gets garbage collected.
-  static void DeleteBreakIterator(v8::Isolate* isolate,
-                                  Persistent<v8::Value>* object,
-                                  void* param);
+  static void DeleteBreakIterator(
+      const v8::WeakCallbackData<v8::Value, void>& data);
 
  private:
   BreakIterator();
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 4633400..208bd91 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -695,228 +695,6 @@
 }
 
 
-void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
-  // TAGGED case:
-  //   Input:
-  //     esp[4]: tagged number input argument (should be number).
-  //     esp[0]: return address.
-  //   Output:
-  //     eax: tagged double result.
-  // UNTAGGED case:
-  //   Input::
-  //     esp[0]: return address.
-  //     xmm1: untagged double input argument
-  //   Output:
-  //     xmm1: untagged double result.
-
-  Label runtime_call;
-  Label runtime_call_clear_stack;
-  Label skip_cache;
-  const bool tagged = (argument_type_ == TAGGED);
-  if (tagged) {
-    // Test that eax is a number.
-    Label input_not_smi;
-    Label loaded;
-    __ mov(eax, Operand(esp, kPointerSize));
-    __ JumpIfNotSmi(eax, &input_not_smi, Label::kNear);
-    // Input is a smi. Untag and load it onto the FPU stack.
-    // Then load the low and high words of the double into ebx, edx.
-    STATIC_ASSERT(kSmiTagSize == 1);
-    __ sar(eax, 1);
-    __ sub(esp, Immediate(2 * kPointerSize));
-    __ mov(Operand(esp, 0), eax);
-    __ fild_s(Operand(esp, 0));
-    __ fst_d(Operand(esp, 0));
-    __ pop(edx);
-    __ pop(ebx);
-    __ jmp(&loaded, Label::kNear);
-    __ bind(&input_not_smi);
-    // Check if input is a HeapNumber.
-    __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-    Factory* factory = masm->isolate()->factory();
-    __ cmp(ebx, Immediate(factory->heap_number_map()));
-    __ j(not_equal, &runtime_call);
-    // Input is a HeapNumber. Push it on the FPU stack and load its
-    // low and high words into ebx, edx.
-    __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
-    __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
-    __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
-
-    __ bind(&loaded);
-  } else {  // UNTAGGED.
-    CpuFeatureScope scope(masm, SSE2);
-    if (CpuFeatures::IsSupported(SSE4_1)) {
-      CpuFeatureScope sse4_scope(masm, SSE4_1);
-      __ pextrd(edx, xmm1, 0x1);  // copy xmm1[63..32] to edx.
-    } else {
-      __ pshufd(xmm0, xmm1, 0x1);
-      __ movd(edx, xmm0);
-    }
-    __ movd(ebx, xmm1);
-  }
-
-  // ST[0] or xmm1  == double value
-  // ebx = low 32 bits of double value
-  // edx = high 32 bits of double value
-  // Compute hash (the shifts are arithmetic):
-  //   h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
-  __ mov(ecx, ebx);
-  __ xor_(ecx, edx);
-  __ mov(eax, ecx);
-  __ sar(eax, 16);
-  __ xor_(ecx, eax);
-  __ mov(eax, ecx);
-  __ sar(eax, 8);
-  __ xor_(ecx, eax);
-  ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
-  __ and_(ecx,
-          Immediate(TranscendentalCache::SubCache::kCacheSize - 1));
-
-  // ST[0] or xmm1 == double value.
-  // ebx = low 32 bits of double value.
-  // edx = high 32 bits of double value.
-  // ecx = TranscendentalCache::hash(double value).
-  ExternalReference cache_array =
-      ExternalReference::transcendental_cache_array_address(masm->isolate());
-  __ mov(eax, Immediate(cache_array));
-  int cache_array_index =
-      type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]);
-  __ mov(eax, Operand(eax, cache_array_index));
-  // Eax points to the cache for the type type_.
-  // If NULL, the cache hasn't been initialized yet, so go through runtime.
-  __ test(eax, eax);
-  __ j(zero, &runtime_call_clear_stack);
-#ifdef DEBUG
-  // Check that the layout of cache elements match expectations.
-  { TranscendentalCache::SubCache::Element test_elem[2];
-    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
-    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
-    char* elem_in0  = reinterpret_cast<char*>(&(test_elem[0].in[0]));
-    char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
-    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
-    CHECK_EQ(12, elem2_start - elem_start);  // Two uint_32's and a pointer.
-    CHECK_EQ(0, elem_in0 - elem_start);
-    CHECK_EQ(kIntSize, elem_in1 - elem_start);
-    CHECK_EQ(2 * kIntSize, elem_out - elem_start);
-  }
-#endif
-  // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12].
-  __ lea(ecx, Operand(ecx, ecx, times_2, 0));
-  __ lea(ecx, Operand(eax, ecx, times_4, 0));
-  // Check if cache matches: Double value is stored in uint32_t[2] array.
-  Label cache_miss;
-  __ cmp(ebx, Operand(ecx, 0));
-  __ j(not_equal, &cache_miss, Label::kNear);
-  __ cmp(edx, Operand(ecx, kIntSize));
-  __ j(not_equal, &cache_miss, Label::kNear);
-  // Cache hit!
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->transcendental_cache_hit(), 1);
-  __ mov(eax, Operand(ecx, 2 * kIntSize));
-  if (tagged) {
-    __ fstp(0);
-    __ ret(kPointerSize);
-  } else {  // UNTAGGED.
-    CpuFeatureScope scope(masm, SSE2);
-    __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
-    __ Ret();
-  }
-
-  __ bind(&cache_miss);
-  __ IncrementCounter(counters->transcendental_cache_miss(), 1);
-  // Update cache with new value.
-  // We are short on registers, so use no_reg as scratch.
-  // This gives slightly larger code.
-  if (tagged) {
-    __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
-  } else {  // UNTAGGED.
-    CpuFeatureScope scope(masm, SSE2);
-    __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
-    __ sub(esp, Immediate(kDoubleSize));
-    __ movsd(Operand(esp, 0), xmm1);
-    __ fld_d(Operand(esp, 0));
-    __ add(esp, Immediate(kDoubleSize));
-  }
-  GenerateOperation(masm, type_);
-  __ mov(Operand(ecx, 0), ebx);
-  __ mov(Operand(ecx, kIntSize), edx);
-  __ mov(Operand(ecx, 2 * kIntSize), eax);
-  __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
-  if (tagged) {
-    __ ret(kPointerSize);
-  } else {  // UNTAGGED.
-    CpuFeatureScope scope(masm, SSE2);
-    __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
-    __ Ret();
-
-    // Skip cache and return answer directly, only in untagged case.
-    __ bind(&skip_cache);
-    __ sub(esp, Immediate(kDoubleSize));
-    __ movsd(Operand(esp, 0), xmm1);
-    __ fld_d(Operand(esp, 0));
-    GenerateOperation(masm, type_);
-    __ fstp_d(Operand(esp, 0));
-    __ movsd(xmm1, Operand(esp, 0));
-    __ add(esp, Immediate(kDoubleSize));
-    // We return the value in xmm1 without adding it to the cache, but
-    // we cause a scavenging GC so that future allocations will succeed.
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-      // Allocate an unused object bigger than a HeapNumber.
-      __ push(Immediate(Smi::FromInt(2 * kDoubleSize)));
-      __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
-    }
-    __ Ret();
-  }
-
-  // Call runtime, doing whatever allocation and cleanup is necessary.
-  if (tagged) {
-    __ bind(&runtime_call_clear_stack);
-    __ fstp(0);
-    __ bind(&runtime_call);
-    ExternalReference runtime =
-        ExternalReference(RuntimeFunction(), masm->isolate());
-    __ TailCallExternalReference(runtime, 1, 1);
-  } else {  // UNTAGGED.
-    CpuFeatureScope scope(masm, SSE2);
-    __ bind(&runtime_call_clear_stack);
-    __ bind(&runtime_call);
-    __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
-    __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-      __ push(eax);
-      __ CallRuntime(RuntimeFunction(), 1);
-    }
-    __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
-    __ Ret();
-  }
-}
-
-
-Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
-  switch (type_) {
-    case TranscendentalCache::LOG: return Runtime::kMath_log;
-    default:
-      UNIMPLEMENTED();
-      return Runtime::kAbort;
-  }
-}
-
-
-void TranscendentalCacheStub::GenerateOperation(
-    MacroAssembler* masm, TranscendentalCache::Type type) {
-  // Only free register is edi.
-  // Input value is on FP stack, and also in ebx/edx.
-  // Input value is possibly in xmm1.
-  // Address of result (a newly allocated HeapNumber) may be in eax.
-  ASSERT(type == TranscendentalCache::LOG);
-  __ fldln2();
-  __ fxch();
-  __ fyl2x();
-}
-
-
 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
                                            Register number) {
   Label load_smi, done;
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
index 1425924..0982fe1 100644
--- a/src/ia32/code-stubs-ia32.h
+++ b/src/ia32/code-stubs-ia32.h
@@ -40,30 +40,6 @@
                      bool construct_call,
                      Label* call_generic_code);
 
-// Compute a transcendental math function natively, or call the
-// TranscendentalCache runtime function.
-class TranscendentalCacheStub: public PlatformCodeStub {
- public:
-  enum ArgumentType {
-    TAGGED = 0,
-    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
-  };
-
-  TranscendentalCacheStub(TranscendentalCache::Type type,
-                          ArgumentType argument_type)
-      : type_(type), argument_type_(argument_type) {}
-  void Generate(MacroAssembler* masm);
-  static void GenerateOperation(MacroAssembler* masm,
-                                TranscendentalCache::Type type);
- private:
-  TranscendentalCache::Type type_;
-  ArgumentType argument_type_;
-
-  Major MajorKey() { return TranscendentalCache; }
-  int MinorKey() { return type_ | argument_type_; }
-  Runtime::FunctionId RuntimeFunction();
-};
-
 
 class StoreBufferOverflowStub: public PlatformCodeStub {
  public:
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 84187b0..99dbe20 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -57,48 +57,6 @@
 #define __ masm.
 
 
-UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
-  size_t actual_size;
-  // Allocate buffer in executable space.
-  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB,
-                                                 &actual_size,
-                                                 true));
-  if (buffer == NULL) {
-    // Fallback to library function if function cannot be created.
-    switch (type) {
-      case TranscendentalCache::LOG: return &log;
-      default: UNIMPLEMENTED();
-    }
-  }
-
-  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
-  // esp[1 * kPointerSize]: raw double input
-  // esp[0 * kPointerSize]: return address
-  // Move double input into registers.
-
-  __ push(ebx);
-  __ push(edx);
-  __ push(edi);
-  __ fld_d(Operand(esp, 4 * kPointerSize));
-  __ mov(ebx, Operand(esp, 4 * kPointerSize));
-  __ mov(edx, Operand(esp, 5 * kPointerSize));
-  TranscendentalCacheStub::GenerateOperation(&masm, type);
-  // The return value is expected to be on ST(0) of the FPU stack.
-  __ pop(edi);
-  __ pop(edx);
-  __ pop(ebx);
-  __ Ret();
-
-  CodeDesc desc;
-  masm.GetCode(&desc);
-  ASSERT(!RelocInfo::RequiresRelocation(desc));
-
-  CPU::FlushICache(buffer, actual_size);
-  OS::ProtectCode(buffer, actual_size);
-  return FUNCTION_CAST<UnaryMathFunction>(buffer);
-}
-
-
 UnaryMathFunction CreateExpFunction() {
   if (!CpuFeatures::IsSupported(SSE2)) return &exp;
   if (!FLAG_fast_math) return &exp;
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 3c92afa..e43e525 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -977,6 +977,16 @@
     Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
     CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
     patch_site.EmitPatchInfo();
+
+    Label skip;
+    __ jmp(&skip, Label::kNear);
+    PrepareForBailout(clause, TOS_REG);
+    __ cmp(eax, isolate()->factory()->true_value());
+    __ j(not_equal, &next_test);
+    __ Drop(1);
+    __ jmp(clause->body_target());
+    __ bind(&skip);
+
     __ test(eax, eax);
     __ j(not_equal, &next_test);
     __ Drop(1);  // Switch value is no longer needed.
@@ -3660,13 +3670,11 @@
 
 
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
-  // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
-                               TranscendentalCacheStub::TAGGED);
+  // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallStub(&stub);
+  __ CallRuntime(Runtime::kMath_log, 1);
   context()->Plug(eax);
 }
 
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index bba3aca..86118eb 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1349,12 +1349,6 @@
       CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
       break;
     }
-    case CodeStub::TranscendentalCache: {
-      TranscendentalCacheStub stub(instr->transcendental_type(),
-                                   TranscendentalCacheStub::TAGGED);
-      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-      break;
-    }
     default:
       UNREACHABLE();
   }
@@ -2259,7 +2253,7 @@
         __ movsd(Operand(esp, 0 * kDoubleSize), left);
         __ movsd(Operand(esp, 1 * kDoubleSize), right);
         __ CallCFunction(
-            ExternalReference::double_fp_operation(Token::MOD, isolate()),
+            ExternalReference::mod_two_doubles_operation(isolate()),
             4);
 
         // Return value is in st(0) on ia32.
@@ -2303,7 +2297,7 @@
         ASSERT(left.is(result));
         X87PrepareToWrite(result);
         __ CallCFunction(
-            ExternalReference::double_fp_operation(Token::MOD, isolate()),
+            ExternalReference::mod_two_doubles_operation(isolate()),
             4);
 
         // Return value is in st(0) on ia32.
@@ -4162,7 +4156,7 @@
   __ xorps(xmm_scratch, xmm_scratch);
   __ ucomisd(input_reg, xmm_scratch);
   __ j(above, &positive, Label::kNear);
-  __ j(equal, &zero, Label::kNear);
+  __ j(not_carry, &zero, Label::kNear);
   ExternalReference nan =
       ExternalReference::address_of_canonical_non_hole_nan();
   __ movsd(input_reg, Operand::StaticVariable(nan));
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index aca9bdf..6e720f1 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1309,8 +1309,7 @@
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->value()->representation().IsDouble());
   LOperand* input = UseRegisterAtStart(instr->value());
-  LMathLog* result = new(zone()) LMathLog(input);
-  return DefineSameAsFirst(result);
+  return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr);
 }
 
 
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 912ec1e..31a1e62 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -498,10 +498,6 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
   DECLARE_HYDROGEN_ACCESSOR(CallStub)
-
-  TranscendentalCache::Type transcendental_type() {
-    return hydrogen()->transcendental_type();
-  }
 };
 
 
diff --git a/src/isolate.cc b/src/isolate.cc
index a0dd958..9ecc7ef 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1532,7 +1532,6 @@
       capture_stack_trace_for_uncaught_exceptions_(false),
       stack_trace_for_uncaught_exceptions_frame_limit_(0),
       stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
-      transcendental_cache_(NULL),
       memory_allocator_(NULL),
       keyed_lookup_cache_(NULL),
       context_slot_cache_(NULL),
@@ -1769,8 +1768,6 @@
   delete keyed_lookup_cache_;
   keyed_lookup_cache_ = NULL;
 
-  delete transcendental_cache_;
-  transcendental_cache_ = NULL;
   delete stub_cache_;
   stub_cache_ = NULL;
   delete stats_table_;
@@ -1935,7 +1932,6 @@
   string_tracker_ = new StringTracker();
   string_tracker_->isolate_ = this;
   compilation_cache_ = new CompilationCache(this);
-  transcendental_cache_ = new TranscendentalCache(this);
   keyed_lookup_cache_ = new KeyedLookupCache();
   context_slot_cache_ = new ContextSlotCache();
   descriptor_lookup_cache_ = new DescriptorLookupCache();
diff --git a/src/isolate.h b/src/isolate.h
index 7ba3088..31a0af8 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -870,10 +870,6 @@
   DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
   ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
 
-  TranscendentalCache* transcendental_cache() const {
-    return transcendental_cache_;
-  }
-
   MemoryAllocator* memory_allocator() {
     return memory_allocator_;
   }
@@ -1270,7 +1266,6 @@
   bool capture_stack_trace_for_uncaught_exceptions_;
   int stack_trace_for_uncaught_exceptions_frame_limit_;
   StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
-  TranscendentalCache* transcendental_cache_;
   MemoryAllocator* memory_allocator_;
   KeyedLookupCache* keyed_lookup_cache_;
   ContextSlotCache* context_slot_cache_;
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index cd1af91..ca765aa 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -1273,224 +1273,6 @@
 }
 
 
-void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
-  // Untagged case: double input in f4, double result goes
-  //   into f4.
-  // Tagged case: tagged input on top of stack and in a0,
-  //   tagged result (heap number) goes into v0.
-
-  Label input_not_smi;
-  Label loaded;
-  Label calculate;
-  Label invalid_cache;
-  const Register scratch0 = t5;
-  const Register scratch1 = t3;
-  const Register cache_entry = a0;
-  const bool tagged = (argument_type_ == TAGGED);
-
-  if (tagged) {
-    // Argument is a number and is on stack and in a0.
-    // Load argument and check if it is a smi.
-    __ JumpIfNotSmi(a0, &input_not_smi);
-
-    // Input is a smi. Convert to double and load the low and high words
-    // of the double into a2, a3.
-    __ sra(t0, a0, kSmiTagSize);
-    __ mtc1(t0, f4);
-    __ cvt_d_w(f4, f4);
-    __ Move(a2, a3, f4);
-    __ Branch(&loaded);
-
-    __ bind(&input_not_smi);
-    // Check if input is a HeapNumber.
-    __ CheckMap(a0,
-                a1,
-                Heap::kHeapNumberMapRootIndex,
-                &calculate,
-                DONT_DO_SMI_CHECK);
-    // Input is a HeapNumber. Store the
-    // low and high words into a2, a3.
-    __ lw(a2, FieldMemOperand(a0, HeapNumber::kValueOffset));
-    __ lw(a3, FieldMemOperand(a0, HeapNumber::kValueOffset + 4));
-  } else {
-    // Input is untagged double in f4. Output goes to f4.
-    __ Move(a2, a3, f4);
-  }
-  __ bind(&loaded);
-  // a2 = low 32 bits of double value.
-  // a3 = high 32 bits of double value.
-  // Compute hash (the shifts are arithmetic):
-  //   h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
-  __ Xor(a1, a2, a3);
-  __ sra(t0, a1, 16);
-  __ Xor(a1, a1, t0);
-  __ sra(t0, a1, 8);
-  __ Xor(a1, a1, t0);
-  ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
-  __ And(a1, a1, Operand(TranscendentalCache::SubCache::kCacheSize - 1));
-
-  // a2 = low 32 bits of double value.
-  // a3 = high 32 bits of double value.
-  // a1 = TranscendentalCache::hash(double value).
-  __ li(cache_entry, Operand(
-      ExternalReference::transcendental_cache_array_address(
-          masm->isolate())));
-  // a0 points to cache array.
-  __ lw(cache_entry, MemOperand(cache_entry, type_ * sizeof(
-      Isolate::Current()->transcendental_cache()->caches_[0])));
-  // a0 points to the cache for the type type_.
-  // If NULL, the cache hasn't been initialized yet, so go through runtime.
-  __ Branch(&invalid_cache, eq, cache_entry, Operand(zero_reg));
-
-#ifdef DEBUG
-  // Check that the layout of cache elements match expectations.
-  { TranscendentalCache::SubCache::Element test_elem[2];
-    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
-    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
-    char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0]));
-    char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1]));
-    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
-    CHECK_EQ(12, elem2_start - elem_start);  // Two uint_32's and a pointer.
-    CHECK_EQ(0, elem_in0 - elem_start);
-    CHECK_EQ(kIntSize, elem_in1 - elem_start);
-    CHECK_EQ(2 * kIntSize, elem_out - elem_start);
-  }
-#endif
-
-  // Find the address of the a1'st entry in the cache, i.e., &a0[a1*12].
-  __ sll(t0, a1, 1);
-  __ Addu(a1, a1, t0);
-  __ sll(t0, a1, 2);
-  __ Addu(cache_entry, cache_entry, t0);
-
-  // Check if cache matches: Double value is stored in uint32_t[2] array.
-  __ lw(t0, MemOperand(cache_entry, 0));
-  __ lw(t1, MemOperand(cache_entry, 4));
-  __ lw(t2, MemOperand(cache_entry, 8));
-  __ Branch(&calculate, ne, a2, Operand(t0));
-  __ Branch(&calculate, ne, a3, Operand(t1));
-  // Cache hit. Load result, cleanup and return.
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(
-      counters->transcendental_cache_hit(), 1, scratch0, scratch1);
-  if (tagged) {
-    // Pop input value from stack and load result into v0.
-    __ Drop(1);
-    __ mov(v0, t2);
-  } else {
-    // Load result into f4.
-    __ ldc1(f4, FieldMemOperand(t2, HeapNumber::kValueOffset));
-  }
-  __ Ret();
-
-  __ bind(&calculate);
-  __ IncrementCounter(
-      counters->transcendental_cache_miss(), 1, scratch0, scratch1);
-  if (tagged) {
-    __ bind(&invalid_cache);
-    __ TailCallExternalReference(ExternalReference(RuntimeFunction(),
-                                                   masm->isolate()),
-                                 1,
-                                 1);
-  } else {
-    Label no_update;
-    Label skip_cache;
-
-    // Call C function to calculate the result and update the cache.
-    // a0: precalculated cache entry address.
-    // a2 and a3: parts of the double value.
-    // Store a0, a2 and a3 on stack for later before calling C function.
-    __ Push(a3, a2, cache_entry);
-    GenerateCallCFunction(masm, scratch0);
-    __ GetCFunctionDoubleResult(f4);
-
-    // Try to update the cache. If we cannot allocate a
-    // heap number, we return the result without updating.
-    __ Pop(a3, a2, cache_entry);
-    __ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(t2, scratch0, scratch1, t1, &no_update);
-    __ sdc1(f4, FieldMemOperand(t2, HeapNumber::kValueOffset));
-
-    __ sw(a2, MemOperand(cache_entry, 0 * kPointerSize));
-    __ sw(a3, MemOperand(cache_entry, 1 * kPointerSize));
-    __ sw(t2, MemOperand(cache_entry, 2 * kPointerSize));
-
-    __ Ret(USE_DELAY_SLOT);
-    __ mov(v0, cache_entry);
-
-    __ bind(&invalid_cache);
-    // The cache is invalid. Call runtime which will recreate the
-    // cache.
-    __ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(a0, scratch0, scratch1, t1, &skip_cache);
-    __ sdc1(f4, FieldMemOperand(a0, HeapNumber::kValueOffset));
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-      __ push(a0);
-      __ CallRuntime(RuntimeFunction(), 1);
-    }
-    __ ldc1(f4, FieldMemOperand(v0, HeapNumber::kValueOffset));
-    __ Ret();
-
-    __ bind(&skip_cache);
-    // Call C function to calculate the result and answer directly
-    // without updating the cache.
-    GenerateCallCFunction(masm, scratch0);
-    __ GetCFunctionDoubleResult(f4);
-    __ bind(&no_update);
-
-    // We return the value in f4 without adding it to the cache, but
-    // we cause a scavenging GC so that future allocations will succeed.
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-
-      // Allocate an aligned object larger than a HeapNumber.
-      ASSERT(4 * kPointerSize >= HeapNumber::kSize);
-      __ li(scratch0, Operand(4 * kPointerSize));
-      __ push(scratch0);
-      __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
-    }
-    __ Ret();
-  }
-}
-
-
-void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
-                                                    Register scratch) {
-  __ push(ra);
-  __ PrepareCallCFunction(2, scratch);
-  if (IsMipsSoftFloatABI) {
-    __ Move(a0, a1, f4);
-  } else {
-    __ mov_d(f12, f4);
-  }
-  AllowExternalCallThatCantCauseGC scope(masm);
-  Isolate* isolate = masm->isolate();
-  switch (type_) {
-    case TranscendentalCache::LOG:
-      __ CallCFunction(
-          ExternalReference::math_log_double_function(isolate),
-          0, 1);
-      break;
-    default:
-      UNIMPLEMENTED();
-      break;
-  }
-  __ pop(ra);
-}
-
-
-Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
-  switch (type_) {
-    // Add more cases when necessary.
-    case TranscendentalCache::LOG: return Runtime::kMath_log;
-    default:
-      UNIMPLEMENTED();
-      return Runtime::kAbort;
-  }
-}
-
-
 void MathPowStub::Generate(MacroAssembler* masm) {
   const Register base = a1;
   const Register exponent = a2;
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index c3e05b8..a0e01b2 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -38,30 +38,6 @@
 void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
 
 
-// Compute a transcendental math function natively, or call the
-// TranscendentalCache runtime function.
-class TranscendentalCacheStub: public PlatformCodeStub {
- public:
-  enum ArgumentType {
-    TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
-    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
-  };
-
-  TranscendentalCacheStub(TranscendentalCache::Type type,
-                          ArgumentType argument_type)
-      : type_(type), argument_type_(argument_type) { }
-  void Generate(MacroAssembler* masm);
- private:
-  TranscendentalCache::Type type_;
-  ArgumentType argument_type_;
-  void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
-
-  Major MajorKey() { return TranscendentalCache; }
-  int MinorKey() { return type_ | argument_type_; }
-  Runtime::FunctionId RuntimeFunction();
-};
-
-
 class StoreBufferOverflowStub: public PlatformCodeStub {
  public:
   explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index cd3a24f..7a20712 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -37,15 +37,6 @@
 namespace internal {
 
 
-UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
-  switch (type) {
-    case TranscendentalCache::LOG: return &log;
-    default: UNIMPLEMENTED();
-  }
-  return NULL;
-}
-
-
 #define __ masm.
 
 
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 74b3807..4b6d280 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -1039,6 +1039,15 @@
     CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
     patch_site.EmitPatchInfo();
 
+    Label skip;
+    __ b(&skip);
+    PrepareForBailout(clause, TOS_REG);
+    __ LoadRoot(at, Heap::kTrueValueRootIndex);
+    __ Branch(&next_test, ne, v0, Operand(at));
+    __ Drop(1);
+    __ jmp(clause->body_target());
+    __ bind(&skip);
+
     __ Branch(&next_test, ne, v0, Operand(zero_reg));
     __ Drop(1);  // Switch value is no longer needed.
     __ Branch(clause->body_target());
@@ -3748,14 +3757,11 @@
 
 
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
-  // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
-                               TranscendentalCacheStub::TAGGED);
+  // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ mov(a0, result_register());  // Stub requires parameter in a0 and on tos.
-  __ CallStub(&stub);
+  __ CallRuntime(Runtime::kMath_log, 1);
   context()->Plug(v0);
 }
 
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index b4d9441..5ac4703 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -1045,13 +1045,6 @@
       CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
       break;
     }
-    case CodeStub::TranscendentalCache: {
-      __ lw(a0, MemOperand(sp, 0));
-      TranscendentalCacheStub stub(instr->transcendental_type(),
-                                   TranscendentalCacheStub::TAGGED);
-      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-      break;
-    }
     default:
       UNREACHABLE();
   }
@@ -1945,7 +1938,7 @@
       __ PrepareCallCFunction(0, 2, scratch0());
       __ SetCallCDoubleArguments(left, right);
       __ CallCFunction(
-          ExternalReference::double_fp_operation(Token::MOD, isolate()),
+          ExternalReference::mod_two_doubles_operation(isolate()),
           0, 2);
       // Move the result in the double result register.
       __ GetCFunctionDoubleResult(result);
@@ -3864,13 +3857,11 @@
 
 
 void LCodeGen::DoMathLog(LMathLog* instr) {
-  ASSERT(ToDoubleRegister(instr->result()).is(f4));
-  // Set the context register to a GC-safe fake value. Clobbering it is
-  // OK because this instruction is marked as a call.
-  __ mov(cp, zero_reg);
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
-                               TranscendentalCacheStub::UNTAGGED);
-  CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
+  __ PrepareCallCFunction(0, 1, scratch0());
+  __ SetCallCDoubleArguments(ToDoubleRegister(instr->value()));
+  __ CallCFunction(ExternalReference::math_log_double_function(isolate()),
+                   0, 1);
+  __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result()));
 }
 
 
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 1ca008c..155ef63 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1201,9 +1201,10 @@
 
 
 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
+  ASSERT(instr->representation().IsDouble());
+  ASSERT(instr->value()->representation().IsDouble());
   LOperand* input = UseFixedDouble(instr->value(), f4);
-  LMathLog* result = new(zone()) LMathLog(input);
-  return MarkAsCall(DefineFixedDouble(result, f4), instr);
+  return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), f4), instr);
 }
 
 
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 99885dc..f0a75c1 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -487,10 +487,6 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
   DECLARE_HYDROGEN_ACCESSOR(CallStub)
-
-  TranscendentalCache::Type transcendental_type() {
-    return hydrogen()->transcendental_type();
-  }
 };
 
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index e81d116..d488fc0 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1297,19 +1297,6 @@
 }
 
 
-bool JSObject::ShouldTrackAllocationInfo() {
-  if (AllocationSite::CanTrack(map()->instance_type())) {
-    if (!IsJSArray()) {
-      return true;
-    }
-
-    return AllocationSite::GetMode(GetElementsKind()) ==
-        TRACK_ALLOCATION_SITE;
-  }
-  return false;
-}
-
-
 void AllocationSite::Initialize() {
   set_transition_info(Smi::FromInt(0));
   SetElementsKind(GetInitialFastElementsKind());
diff --git a/src/objects.h b/src/objects.h
index 5a2d559..28de179 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2117,8 +2117,6 @@
   bool HasDictionaryArgumentsElements();
   inline SeededNumberDictionary* element_dictionary();  // Gets slow elements.
 
-  inline bool ShouldTrackAllocationInfo();
-
   inline void set_map_and_elements(
       Map* map,
       FixedArrayBase* value,
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index 0070bdf..02a7b76 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -302,7 +302,6 @@
   return (*fast_##name##_function)(x);                   \
 }
 
-UNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG))
 UNARY_MATH_FUNCTION(exp, CreateExpFunction())
 UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
 
@@ -527,7 +526,6 @@
   OS::memcopy_uint8_function =
       CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
 #endif
-  init_fast_log_function();
   // fast_exp is initialized lazily.
   init_fast_sqrt_function();
 }
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 7ca5e55..546d31c 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -196,7 +196,6 @@
   return (*fast_##name##_function)(x);                   \
 }
 
-UNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG))
 UNARY_MATH_FUNCTION(exp, CreateExpFunction())
 UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
 
@@ -214,7 +213,6 @@
 #ifdef _WIN64
   init_modulo_function();
 #endif
-  init_fast_log_function();
   // fast_exp is initialized lazily.
   init_fast_sqrt_function();
 }
diff --git a/src/platform.h b/src/platform.h
index f94a526..6cf3062 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -96,7 +96,6 @@
 double modulo(double x, double y);
 
 // Custom implementation of math functions.
-double fast_log(double input);
 double fast_exp(double input);
 double fast_sqrt(double input);
 // The custom exp implementation needs 16KB of lookup data; initialize it
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index acf54da..6bd446e 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -352,9 +352,8 @@
 }
 
 
-CpuProfile::CpuProfile(const char* title, unsigned uid, bool record_samples)
+CpuProfile::CpuProfile(const char* title, bool record_samples)
     : title_(title),
-      uid_(uid),
       record_samples_(record_samples),
       start_time_(Time::NowFromSystemTime()) {
   timer_.Start();
@@ -486,9 +485,8 @@
 }
 
 
-bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid,
+bool CpuProfilesCollection::StartProfiling(const char* title,
                                            bool record_samples) {
-  ASSERT(uid > 0);
   current_profiles_semaphore_.Wait();
   if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
     current_profiles_semaphore_.Signal();
@@ -501,7 +499,7 @@
       return false;
     }
   }
-  current_profiles_.Add(new CpuProfile(title, uid, record_samples));
+  current_profiles_.Add(new CpuProfile(title, record_samples));
   current_profiles_semaphore_.Signal();
   return true;
 }
@@ -537,9 +535,8 @@
 
 void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) {
   // Called from VM thread for a completed profile.
-  unsigned uid = profile->uid();
   for (int i = 0; i < finished_profiles_.length(); i++) {
-    if (uid == finished_profiles_[i]->uid()) {
+    if (profile == finished_profiles_[i]) {
       finished_profiles_.Remove(i);
       return;
     }
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 6e4758b..81980bf 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -196,14 +196,13 @@
 
 class CpuProfile {
  public:
-  CpuProfile(const char* title, unsigned uid, bool record_samples);
+  CpuProfile(const char* title, bool record_samples);
 
   // Add pc -> ... -> main() call path to the profile.
   void AddPath(const Vector<CodeEntry*>& path);
   void CalculateTotalTicksAndSamplingRate();
 
   const char* title() const { return title_; }
-  unsigned uid() const { return uid_; }
   const ProfileTree* top_down() const { return &top_down_; }
 
   int samples_count() const { return samples_.length(); }
@@ -218,7 +217,6 @@
 
  private:
   const char* title_;
-  unsigned uid_;
   bool record_samples_;
   Time start_time_;
   Time end_time_;
@@ -281,7 +279,7 @@
   explicit CpuProfilesCollection(Heap* heap);
   ~CpuProfilesCollection();
 
-  bool StartProfiling(const char* title, unsigned uid, bool record_samples);
+  bool StartProfiling(const char* title, bool record_samples);
   CpuProfile* StopProfiling(const char* title);
   List<CpuProfile*>* profiles() { return &finished_profiles_; }
   const char* GetName(Name* name) {
diff --git a/src/rewriter.cc b/src/rewriter.cc
index ba35284..5e81cf8 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -207,11 +207,6 @@
 }
 
 
-void Processor::VisitCaseClause(CaseClause* clause) {
-  UNREACHABLE();
-}
-
-
 void Processor::VisitContinueStatement(ContinueStatement* node) {
   is_set_ = false;
 }
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 8c4b11f..390222d 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -66,7 +66,7 @@
     100 * FullCodeGenerator::kCodeSizeMultiplier;
 
 static const int kOSRCodeSizeAllowancePerTick =
-    3 * FullCodeGenerator::kCodeSizeMultiplier;
+    4 * FullCodeGenerator::kCodeSizeMultiplier;
 
 // Maximum size in bytes of generated code for a function to be optimized
 // the very first time it is seen on the stack.
diff --git a/src/runtime.cc b/src/runtime.cc
index 8d84fda..4d84a15 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -7732,7 +7732,7 @@
   isolate->counters()->math_log()->Increment();
 
   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return isolate->heap()->AllocateHeapNumber(fast_log(x));
+  return isolate->heap()->AllocateHeapNumber(log(x));
 }
 
 
@@ -9949,8 +9949,7 @@
   }
 
   inline void clear_storage() {
-    isolate_->global_handles()->Destroy(
-        Handle<Object>::cast(storage_).location());
+    GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
   }
 
   inline void set_storage(FixedArray* storage) {
@@ -13806,8 +13805,8 @@
 
   // Make object handle weak so we can delete the data format once GC kicks in.
   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
-                          NULL,
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
                           DateFormat::DeleteDateFormat);
   return *local_object;
 }
@@ -13910,8 +13909,8 @@
           NONE));
 
   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
-                          NULL,
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
                           NumberFormat::DeleteNumberFormat);
   return *local_object;
 }
@@ -14022,8 +14021,8 @@
           NONE));
 
   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
-                          NULL,
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
                           Collator::DeleteCollator);
   return *local_object;
 }
@@ -14098,8 +14097,8 @@
   // Make object handle weak so we can delete the break iterator once GC kicks
   // in.
   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(wrapper.location()),
-                          NULL,
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
                           BreakIterator::DeleteBreakIterator);
   return *local_object;
 }
diff --git a/src/serialize.cc b/src/serialize.cc
index a0a66f9..5adc2b8 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -378,30 +378,10 @@
       17,
       "Debug::step_in_fp_addr()");
 #endif
-  Add(ExternalReference::double_fp_operation(Token::ADD, isolate).address(),
-      UNCLASSIFIED,
-      18,
-      "add_two_doubles");
-  Add(ExternalReference::double_fp_operation(Token::SUB, isolate).address(),
-      UNCLASSIFIED,
-      19,
-      "sub_two_doubles");
-  Add(ExternalReference::double_fp_operation(Token::MUL, isolate).address(),
-      UNCLASSIFIED,
-      20,
-      "mul_two_doubles");
-  Add(ExternalReference::double_fp_operation(Token::DIV, isolate).address(),
-      UNCLASSIFIED,
-      21,
-      "div_two_doubles");
-  Add(ExternalReference::double_fp_operation(Token::MOD, isolate).address(),
+  Add(ExternalReference::mod_two_doubles_operation(isolate).address(),
       UNCLASSIFIED,
       22,
       "mod_two_doubles");
-  Add(ExternalReference::compare_doubles(isolate).address(),
-      UNCLASSIFIED,
-      23,
-      "compare_doubles");
 #ifndef V8_INTERPRETED_REGEXP
   Add(ExternalReference::re_case_insensitive_compare_uc16(isolate).address(),
       UNCLASSIFIED,
@@ -429,10 +409,6 @@
       UNCLASSIFIED,
       29,
       "KeyedLookupCache::field_offsets()");
-  Add(ExternalReference::transcendental_cache_array_address(isolate).address(),
-      UNCLASSIFIED,
-      30,
-      "TranscendentalCache::caches()");
   Add(ExternalReference::handle_scope_next_address(isolate).address(),
       UNCLASSIFIED,
       31,
diff --git a/src/type-info.cc b/src/type-info.cc
index eed54ce..73d8c75 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -320,18 +320,6 @@
 }
 
 
-Handle<Type> TypeFeedbackOracle::ClauseType(TypeFeedbackId id) {
-  Handle<Object> info = GetInfo(id);
-  Handle<Type> result(Type::None(), isolate_);
-  if (info->IsCode() && Handle<Code>::cast(info)->is_compare_ic_stub()) {
-    Handle<Code> code = Handle<Code>::cast(info);
-    CompareIC::State state = ICCompareStub::CompareState(code->stub_info());
-    result = CompareIC::StateToType(isolate_, state);
-  }
-  return result;
-}
-
-
 Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) {
   Handle<Object> object = GetInfo(id);
   if (!object->IsCode()) return handle(Type::None(), isolate_);
diff --git a/src/type-info.h b/src/type-info.h
index 0ff99e9..8bad5c0 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -303,8 +303,6 @@
 
   Handle<Type> CountType(TypeFeedbackId id);
 
-  Handle<Type> ClauseType(TypeFeedbackId id);
-
   Zone* zone() const { return zone_; }
   Isolate* isolate() const { return isolate_; }
 
diff --git a/src/typing.cc b/src/typing.cc
index 9458d6d..de9f404 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -27,6 +27,8 @@
 
 #include "typing.h"
 
+#include "frames.h"
+#include "frames-inl.h"
 #include "parser.h"  // for CompileTimeValue; TODO(rossberg): should move
 #include "scopes.h"
 
@@ -68,6 +70,75 @@
 
 #undef RECURSE
 
+
+Effect AstTyper::ObservedOnStack(Object* value) {
+  Type* lower = Type::OfCurrently(Handle<Object>(value, isolate()));
+  return Effect(Bounds(lower, Type::Any(), isolate()));
+}
+
+
+#ifdef OBJECT_PRINT
+  static void PrintObserved(Variable* var, Object* value, Handle<Type> type) {
+    PrintF("  observed %s ", var->IsParameter() ? "param" : "local");
+    var->name()->Print();
+    PrintF(" : ");
+    value->ShortPrint();
+    PrintF(" -> ");
+    type->TypePrint();
+  }
+#endif  // OBJECT_PRINT
+
+
+void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
+  if (stmt->OsrEntryId() != info_->osr_ast_id()) return;
+
+  DisallowHeapAllocation no_gc;
+  JavaScriptFrameIterator it(isolate());
+  JavaScriptFrame* frame = it.frame();
+  Scope* scope = info_->scope();
+
+  // Assert that the frame on the stack belongs to the function we want to OSR.
+  ASSERT_EQ(*info_->closure(), frame->function());
+
+  int params = scope->num_parameters();
+  int locals = scope->StackLocalCount();
+
+  // Use sequential composition to achieve desired narrowing.
+  // The receiver is a parameter with index -1.
+  store_.Seq(parameter_index(-1), ObservedOnStack(frame->receiver()));
+  for (int i = 0; i < params; i++) {
+    store_.Seq(parameter_index(i), ObservedOnStack(frame->GetParameter(i)));
+  }
+
+  for (int i = 0; i < locals; i++) {
+    store_.Seq(stack_local_index(i), ObservedOnStack(frame->GetExpression(i)));
+  }
+
+#ifdef OBJECT_PRINT
+  if (FLAG_trace_osr && FLAG_print_scopes) {
+    PrintObserved(scope->receiver(),
+                  frame->receiver(),
+                  store_.LookupBounds(parameter_index(-1)).lower);
+
+    for (int i = 0; i < params; i++) {
+      PrintObserved(scope->parameter(i),
+                    frame->GetParameter(i),
+                    store_.LookupBounds(parameter_index(i)).lower);
+    }
+
+    ZoneList<Variable*> local_vars(locals, zone());
+    ZoneList<Variable*> context_vars(scope->ContextLocalCount(), zone());
+    scope->CollectStackAndContextLocals(&local_vars, &context_vars);
+    for (int i = 0; i < locals; i++) {
+      PrintObserved(local_vars.at(i),
+                    frame->GetExpression(i),
+                    store_.LookupBounds(stack_local_index(i)).lower);
+    }
+  }
+#endif  // OBJECT_PRINT
+}
+
+
 #define RECURSE(call)                \
   do {                               \
     ASSERT(!HasStackOverflow());     \
@@ -151,24 +222,23 @@
   RECURSE(Visit(stmt->tag()));
 
   ZoneList<CaseClause*>* clauses = stmt->cases();
-  SwitchStatement::SwitchType switch_type = stmt->switch_type();
   Effects local_effects(zone());
   bool complex_effects = false;  // True for label effects or fall-through.
 
   for (int i = 0; i < clauses->length(); ++i) {
     CaseClause* clause = clauses->at(i);
+
     Effects clause_effects = EnterEffects();
 
     if (!clause->is_default()) {
       Expression* label = clause->label();
-      SwitchStatement::SwitchType label_switch_type =
-          label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH :
-          label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH :
-              SwitchStatement::GENERIC_SWITCH;
-      if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
-        switch_type = label_switch_type;
-      else if (switch_type != label_switch_type)
-        switch_type = SwitchStatement::GENERIC_SWITCH;
+      // Collect type feedback.
+      Handle<Type> tag_type, label_type, combined_type;
+      oracle()->CompareType(clause->CompareId(),
+                            &tag_type, &label_type, &combined_type);
+      NarrowLowerType(stmt->tag(), tag_type);
+      NarrowLowerType(label, label_type);
+      clause->set_compare_type(combined_type);
 
       RECURSE(Visit(label));
       if (!clause_effects.IsEmpty()) complex_effects = true;
@@ -189,20 +259,6 @@
   } else {
     store_.Seq(local_effects);
   }
-
-  if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
-    switch_type = SwitchStatement::GENERIC_SWITCH;
-  stmt->set_switch_type(switch_type);
-
-  // Collect type feedback.
-  // TODO(rossberg): can we eliminate this special case and extra loop?
-  if (switch_type == SwitchStatement::SMI_SWITCH) {
-    for (int i = 0; i < clauses->length(); ++i) {
-      CaseClause* clause = clauses->at(i);
-      if (!clause->is_default())
-        clause->set_compare_type(oracle()->ClauseType(clause->CompareId()));
-    }
-  }
 }
 
 
@@ -221,6 +277,7 @@
   // computing the set of variables assigned in only some of the origins of the
   // control transfer (such as the loop body here).
   store_.Forget();  // Control may transfer here via looping or 'continue'.
+  ObserveTypesAtOsrEntry(stmt);
   RECURSE(Visit(stmt->body()));
   RECURSE(Visit(stmt->cond()));
   store_.Forget();  // Control may transfer here via 'break'.
@@ -235,6 +292,7 @@
 
   store_.Forget();  // Control may transfer here via looping or 'continue'.
   RECURSE(Visit(stmt->cond()));
+  ObserveTypesAtOsrEntry(stmt);
   RECURSE(Visit(stmt->body()));
   store_.Forget();  // Control may transfer here via termination or 'break'.
 }
@@ -251,6 +309,7 @@
 
     RECURSE(Visit(stmt->cond()));
   }
+  ObserveTypesAtOsrEntry(stmt);
   RECURSE(Visit(stmt->body()));
   if (stmt->next() != NULL) {
     store_.Forget();  // Control may transfer here via 'continue'.
@@ -267,6 +326,7 @@
 
   RECURSE(Visit(stmt->enumerable()));
   store_.Forget();  // Control may transfer here via looping or 'continue'.
+  ObserveTypesAtOsrEntry(stmt);
   RECURSE(Visit(stmt->body()));
   store_.Forget();  // Control may transfer here via 'break'.
 }
diff --git a/src/typing.h b/src/typing.h
index a111ae5..ec9132f 100644
--- a/src/typing.h
+++ b/src/typing.h
@@ -58,6 +58,9 @@
  private:
   explicit AstTyper(CompilationInfo* info);
 
+  Effect ObservedOnStack(Object* value);
+  void ObserveTypesAtOsrEntry(IterationStatement* stmt);
+
   static const int kNoVar = INT_MIN;
   typedef v8::internal::Effects<int, kNoVar> Effects;
   typedef v8::internal::NestedEffects<int, kNoVar> Store;
@@ -82,12 +85,15 @@
   }
   void ExitEffects() { store_ = store_.Pop(); }
 
+  int parameter_index(int index) { return -index - 2; }
+  int stack_local_index(int index) { return index; }
+
   int variable_index(Variable* var) {
     // Stack locals have the range [0 .. l]
     // Parameters have the range [-1 .. p]
     // We map this to [-p-2 .. -1, 0 .. l]
-    return var->IsStackLocal() ? var->index() :
-           var->IsParameter() ? -var->index() - 2 : kNoVar;
+    return var->IsStackLocal() ? stack_local_index(var->index()) :
+           var->IsParameter() ? parameter_index(var->index()) : kNoVar;
   }
 
   void VisitDeclarations(ZoneList<Declaration*>* declarations);
diff --git a/src/utils.h b/src/utils.h
index 3a0936e..14a4c56 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1118,6 +1118,7 @@
 
   bool IsNone() const { return id_ == kNoneId; }
   bool operator==(const BailoutId& other) const { return id_ == other.id_; }
+  bool operator!=(const BailoutId& other) const { return id_ != other.id_; }
 
  private:
   static const int kNoneId = -1;
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 72f5650..0bd4955 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -248,8 +248,6 @@
   SC(math_pow, V8.MathPow)                                            \
   SC(math_round, V8.MathRound)                                        \
   SC(math_sqrt, V8.MathSqrt)                                          \
-  SC(transcendental_cache_hit, V8.TranscendentalCacheHit)             \
-  SC(transcendental_cache_miss, V8.TranscendentalCacheMiss)           \
   SC(stack_interrupts, V8.StackInterrupts)                            \
   SC(runtime_profiler_ticks, V8.RuntimeProfilerTicks)                 \
   SC(bounds_checks_eliminated, V8.BoundsChecksEliminated)             \
diff --git a/src/version.cc b/src/version.cc
index 99b44d3..1a8f1c0 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     24
-#define BUILD_NUMBER      3
+#define BUILD_NUMBER      4
 #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/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index d04e976..5b5212c 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -597,220 +597,6 @@
 }
 
 
-void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
-  // TAGGED case:
-  //   Input:
-  //     rsp[8] : argument (should be number).
-  //     rsp[0] : return address.
-  //   Output:
-  //     rax: tagged double result.
-  // UNTAGGED case:
-  //   Input::
-  //     rsp[0] : return address.
-  //     xmm1   : untagged double input argument
-  //   Output:
-  //     xmm1   : untagged double result.
-
-  Label runtime_call;
-  Label runtime_call_clear_stack;
-  Label skip_cache;
-  const bool tagged = (argument_type_ == TAGGED);
-  if (tagged) {
-    Label input_not_smi, loaded;
-
-    // Test that rax is a number.
-    StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
-    __ movq(rax, args.GetArgumentOperand(0));
-    __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
-    // Input is a smi. Untag and load it onto the FPU stack.
-    // Then load the bits of the double into rbx.
-    __ SmiToInteger32(rax, rax);
-    __ subq(rsp, Immediate(kDoubleSize));
-    __ Cvtlsi2sd(xmm1, rax);
-    __ movsd(Operand(rsp, 0), xmm1);
-    __ movq(rbx, xmm1);
-    __ movq(rdx, xmm1);
-    __ fld_d(Operand(rsp, 0));
-    __ addq(rsp, Immediate(kDoubleSize));
-    __ jmp(&loaded, Label::kNear);
-
-    __ bind(&input_not_smi);
-    // Check if input is a HeapNumber.
-    __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex);
-    __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
-    __ j(not_equal, &runtime_call);
-    // Input is a HeapNumber. Push it on the FPU stack and load its
-    // bits into rbx.
-    __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
-    __ MoveDouble(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
-    __ movq(rdx, rbx);
-
-    __ bind(&loaded);
-  } else {  // UNTAGGED.
-    __ movq(rbx, xmm1);
-    __ movq(rdx, xmm1);
-  }
-
-  // ST[0] == double value, if TAGGED.
-  // rbx = bits of double value.
-  // rdx = also bits of double value.
-  // Compute hash (h is 32 bits, bits are 64 and the shifts are arithmetic):
-  //   h = h0 = bits ^ (bits >> 32);
-  //   h ^= h >> 16;
-  //   h ^= h >> 8;
-  //   h = h & (cacheSize - 1);
-  // or h = (h0 ^ (h0 >> 8) ^ (h0 >> 16) ^ (h0 >> 24)) & (cacheSize - 1)
-  __ sar(rdx, Immediate(32));
-  __ xorl(rdx, rbx);
-  __ movl(rcx, rdx);
-  __ movl(rax, rdx);
-  __ movl(rdi, rdx);
-  __ sarl(rdx, Immediate(8));
-  __ sarl(rcx, Immediate(16));
-  __ sarl(rax, Immediate(24));
-  __ xorl(rcx, rdx);
-  __ xorl(rax, rdi);
-  __ xorl(rcx, rax);
-  ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
-  __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1));
-
-  // ST[0] == double value.
-  // rbx = bits of double value.
-  // rcx = TranscendentalCache::hash(double value).
-  ExternalReference cache_array =
-      ExternalReference::transcendental_cache_array_address(masm->isolate());
-  __ Move(rax, cache_array);
-  int cache_array_index =
-      type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]);
-  __ movq(rax, Operand(rax, cache_array_index));
-  // rax points to the cache for the type type_.
-  // If NULL, the cache hasn't been initialized yet, so go through runtime.
-  __ testq(rax, rax);
-  __ j(zero, &runtime_call_clear_stack);  // Only clears stack if TAGGED.
-#ifdef DEBUG
-  // Check that the layout of cache elements match expectations.
-  {  // NOLINT - doesn't like a single brace on a line.
-    TranscendentalCache::SubCache::Element test_elem[2];
-    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
-    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
-    char* elem_in0  = reinterpret_cast<char*>(&(test_elem[0].in[0]));
-    char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
-    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
-    // Two uint_32's and a pointer per element.
-    CHECK_EQ(2 * kIntSize + 1 * kPointerSize,
-             static_cast<int>(elem2_start - elem_start));
-    CHECK_EQ(0, static_cast<int>(elem_in0 - elem_start));
-    CHECK_EQ(kIntSize, static_cast<int>(elem_in1 - elem_start));
-    CHECK_EQ(2 * kIntSize, static_cast<int>(elem_out - elem_start));
-  }
-#endif
-  // Find the address of the rcx'th entry in the cache, i.e., &rax[rcx*16].
-  __ addl(rcx, rcx);
-  __ lea(rcx, Operand(rax, rcx, times_8, 0));
-  // Check if cache matches: Double value is stored in uint32_t[2] array.
-  Label cache_miss;
-  __ cmpq(rbx, Operand(rcx, 0));
-  __ j(not_equal, &cache_miss, Label::kNear);
-  // Cache hit!
-  Counters* counters = masm->isolate()->counters();
-  __ IncrementCounter(counters->transcendental_cache_hit(), 1);
-  __ movq(rax, Operand(rcx, 2 * kIntSize));
-  if (tagged) {
-    __ fstp(0);  // Clear FPU stack.
-    __ ret(kPointerSize);
-  } else {  // UNTAGGED.
-    __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
-    __ Ret();
-  }
-
-  __ bind(&cache_miss);
-  __ IncrementCounter(counters->transcendental_cache_miss(), 1);
-  // Update cache with new value.
-  if (tagged) {
-  __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack);
-  } else {  // UNTAGGED.
-    __ AllocateHeapNumber(rax, rdi, &skip_cache);
-    __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1);
-    __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
-  }
-  GenerateOperation(masm, type_);
-  __ movq(Operand(rcx, 0), rbx);
-  __ movq(Operand(rcx, 2 * kIntSize), rax);
-  __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
-  if (tagged) {
-    __ ret(kPointerSize);
-  } else {  // UNTAGGED.
-    __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
-    __ Ret();
-
-    // Skip cache and return answer directly, only in untagged case.
-    __ bind(&skip_cache);
-    __ subq(rsp, Immediate(kDoubleSize));
-    __ movsd(Operand(rsp, 0), xmm1);
-    __ fld_d(Operand(rsp, 0));
-    GenerateOperation(masm, type_);
-    __ fstp_d(Operand(rsp, 0));
-    __ movsd(xmm1, Operand(rsp, 0));
-    __ addq(rsp, Immediate(kDoubleSize));
-    // We return the value in xmm1 without adding it to the cache, but
-    // we cause a scavenging GC so that future allocations will succeed.
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-      // Allocate an unused object bigger than a HeapNumber.
-      __ Push(Smi::FromInt(2 * kDoubleSize));
-      __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
-    }
-    __ Ret();
-  }
-
-  // Call runtime, doing whatever allocation and cleanup is necessary.
-  if (tagged) {
-    __ bind(&runtime_call_clear_stack);
-    __ fstp(0);
-    __ bind(&runtime_call);
-    __ TailCallExternalReference(
-        ExternalReference(RuntimeFunction(), masm->isolate()), 1, 1);
-  } else {  // UNTAGGED.
-    __ bind(&runtime_call_clear_stack);
-    __ bind(&runtime_call);
-    __ AllocateHeapNumber(rax, rdi, &skip_cache);
-    __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1);
-    {
-      FrameScope scope(masm, StackFrame::INTERNAL);
-      __ push(rax);
-      __ CallRuntime(RuntimeFunction(), 1);
-    }
-    __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
-    __ Ret();
-  }
-}
-
-
-Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
-  switch (type_) {
-    // Add more cases when necessary.
-    case TranscendentalCache::LOG: return Runtime::kMath_log;
-    default:
-      UNIMPLEMENTED();
-      return Runtime::kAbort;
-  }
-}
-
-
-void TranscendentalCacheStub::GenerateOperation(
-    MacroAssembler* masm, TranscendentalCache::Type type) {
-  // Registers:
-  // rax: Newly allocated HeapNumber, which must be preserved.
-  // rbx: Bits of input double. Must be preserved.
-  // rcx: Pointer to cache entry. Must be preserved.
-  // st(0): Input double
-  ASSERT(type == TranscendentalCache::LOG);
-  __ fldln2();
-  __ fxch();
-  __ fyl2x();
-}
-
-
 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
                                                   Label* not_numbers) {
   Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, load_float_rax, done;
diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h
index 7a3f6a6..3c5666e 100644
--- a/src/x64/code-stubs-x64.h
+++ b/src/x64/code-stubs-x64.h
@@ -37,31 +37,6 @@
 
 void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
 
-// Compute a transcendental math function natively, or call the
-// TranscendentalCache runtime function.
-class TranscendentalCacheStub: public PlatformCodeStub {
- public:
-  enum ArgumentType {
-    TAGGED = 0,
-    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
-  };
-
-  explicit TranscendentalCacheStub(TranscendentalCache::Type type,
-                                   ArgumentType argument_type)
-      : type_(type), argument_type_(argument_type) {}
-  void Generate(MacroAssembler* masm);
-  static void GenerateOperation(MacroAssembler* masm,
-                                TranscendentalCache::Type type);
- private:
-  TranscendentalCache::Type type_;
-  ArgumentType argument_type_;
-
-  Major MajorKey() { return TranscendentalCache; }
-  int MinorKey() { return type_ | argument_type_; }
-  Runtime::FunctionId RuntimeFunction();
-};
-
-
 class StoreBufferOverflowStub: public PlatformCodeStub {
  public:
   explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 96d930e..d224e60 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -55,47 +55,6 @@
 #define __ masm.
 
 
-UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
-  size_t actual_size;
-  // Allocate buffer in executable space.
-  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB,
-                                                 &actual_size,
-                                                 true));
-  if (buffer == NULL) {
-    // Fallback to library function if function cannot be created.
-    switch (type) {
-      case TranscendentalCache::LOG: return &log;
-      default: UNIMPLEMENTED();
-    }
-  }
-
-  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
-  // xmm0: raw double input.
-  // Move double input into registers.
-  __ push(rbx);
-  __ push(rdi);
-  __ movq(rbx, xmm0);
-  __ push(rbx);
-  __ fld_d(Operand(rsp, 0));
-  TranscendentalCacheStub::GenerateOperation(&masm, type);
-  // The return value is expected to be in xmm0.
-  __ fstp_d(Operand(rsp, 0));
-  __ pop(rbx);
-  __ movq(xmm0, rbx);
-  __ pop(rdi);
-  __ pop(rbx);
-  __ Ret();
-
-  CodeDesc desc;
-  masm.GetCode(&desc);
-  ASSERT(!RelocInfo::RequiresRelocation(desc));
-
-  CPU::FlushICache(buffer, actual_size);
-  OS::ProtectCode(buffer, actual_size);
-  return FUNCTION_CAST<UnaryMathFunction>(buffer);
-}
-
-
 UnaryMathFunction CreateExpFunction() {
   if (!FLAG_fast_math) return &exp;
   size_t actual_size;
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 473f548..a56f223 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -986,6 +986,15 @@
     CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
     patch_site.EmitPatchInfo();
 
+    Label skip;
+    __ jmp(&skip, Label::kNear);
+    PrepareForBailout(clause, TOS_REG);
+    __ CompareRoot(rax, Heap::kTrueValueRootIndex);
+    __ j(not_equal, &next_test);
+    __ Drop(1);
+    __ jmp(clause->body_target());
+    __ bind(&skip);
+
     __ testq(rax, rax);
     __ j(not_equal, &next_test);
     __ Drop(1);  // Switch value is no longer needed.
@@ -3628,13 +3637,11 @@
 
 
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
-  // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
-                               TranscendentalCacheStub::TAGGED);
+  // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallStub(&stub);
+  __ CallRuntime(Runtime::kMath_log, 1);
   context()->Plug(rax);
 }
 
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index c6d5a14..c392b45 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -968,12 +968,6 @@
       CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
       break;
     }
-    case CodeStub::TranscendentalCache: {
-      TranscendentalCacheStub stub(instr->transcendental_type(),
-                                   TranscendentalCacheStub::TAGGED);
-      CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-      break;
-    }
     default:
       UNREACHABLE();
   }
@@ -1904,7 +1898,7 @@
       __ movaps(xmm_scratch, left);
       ASSERT(right.is(xmm1));
       __ CallCFunction(
-          ExternalReference::double_fp_operation(Token::MOD, isolate()), 2);
+          ExternalReference::mod_two_doubles_operation(isolate()), 2);
       __ movaps(result, xmm_scratch);
       break;
     }
@@ -3732,7 +3726,7 @@
   __ xorps(xmm_scratch, xmm_scratch);
   __ ucomisd(input_reg, xmm_scratch);
   __ j(above, &positive, Label::kNear);
-  __ j(equal, &zero, Label::kNear);
+  __ j(not_carry, &zero, Label::kNear);
   ExternalReference nan =
       ExternalReference::address_of_canonical_non_hole_nan();
   Operand nan_operand = masm()->ExternalOperand(nan);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 974a970..480adf8 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1223,8 +1223,7 @@
   ASSERT(instr->representation().IsDouble());
   ASSERT(instr->value()->representation().IsDouble());
   LOperand* input = UseRegisterAtStart(instr->value());
-  LMathLog* result = new(zone()) LMathLog(input);
-  return DefineSameAsFirst(result);
+  return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr);
 }
 
 
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index e644c2d..7ba1d30 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -489,10 +489,6 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
   DECLARE_HYDROGEN_ACCESSOR(CallStub)
-
-  TranscendentalCache::Type transcendental_type() {
-    return hydrogen()->transcendental_type();
-  }
 };