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();
- }
};