| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 case kNonPrimitive: return "non-primitive"; | 341 case kNonPrimitive: return "non-primitive"; |
| 342 case kJSArray: return "array"; | 342 case kJSArray: return "array"; |
| 343 case kJSObject: return "object"; | 343 case kJSObject: return "object"; |
| 344 case kUninitialized: return "uninitialized"; | 344 case kUninitialized: return "uninitialized"; |
| 345 } | 345 } |
| 346 UNREACHABLE(); | 346 UNREACHABLE(); |
| 347 return "Unreachable code"; | 347 return "Unreachable code"; |
| 348 } | 348 } |
| 349 | 349 |
| 350 | 350 |
| 351 HType HType::TypeFromValue(Isolate* isolate, Handle<Object> value) { | 351 HType HType::TypeFromValue(Handle<Object> value) { |
| 352 // Handle dereferencing is safe here: an object's type as checked below | |
| 353 // never changes. | |
| 354 AllowHandleDereference allow_handle_deref(isolate); | |
| 355 | |
| 356 HType result = HType::Tagged(); | 352 HType result = HType::Tagged(); |
| 357 if (value->IsSmi()) { | 353 if (value->IsSmi()) { |
| 358 result = HType::Smi(); | 354 result = HType::Smi(); |
| 359 } else if (value->IsHeapNumber()) { | 355 } else if (value->IsHeapNumber()) { |
| 360 result = HType::HeapNumber(); | 356 result = HType::HeapNumber(); |
| 361 } else if (value->IsString()) { | 357 } else if (value->IsString()) { |
| 362 result = HType::String(); | 358 result = HType::String(); |
| 363 } else if (value->IsBoolean()) { | 359 } else if (value->IsBoolean()) { |
| 364 result = HType::Boolean(); | 360 result = HType::Boolean(); |
| 365 } else if (value->IsJSObject()) { | 361 } else if (value->IsJSObject()) { |
| (...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 | 1298 |
| 1303 | 1299 |
| 1304 HValue* HCheckInstanceType::Canonicalize() { | 1300 HValue* HCheckInstanceType::Canonicalize() { |
| 1305 if (check_ == IS_STRING && | 1301 if (check_ == IS_STRING && |
| 1306 !value()->type().IsUninitialized() && | 1302 !value()->type().IsUninitialized() && |
| 1307 value()->type().IsString()) { | 1303 value()->type().IsString()) { |
| 1308 return NULL; | 1304 return NULL; |
| 1309 } | 1305 } |
| 1310 | 1306 |
| 1311 if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) { | 1307 if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) { |
| 1312 // Dereferencing is safe here: | 1308 if (HConstant::cast(value())->HasInternalizedStringValue()) return NULL; |
| 1313 // an internalized string cannot become non-internalized. | |
| 1314 AllowHandleDereference allow_handle_deref(isolate()); | |
| 1315 if (HConstant::cast(value())->handle()->IsInternalizedString()) return NULL; | |
| 1316 } | 1309 } |
| 1317 return this; | 1310 return this; |
| 1318 } | 1311 } |
| 1319 | 1312 |
| 1320 | 1313 |
| 1321 void HCheckInstanceType::GetCheckInterval(InstanceType* first, | 1314 void HCheckInstanceType::GetCheckInterval(InstanceType* first, |
| 1322 InstanceType* last) { | 1315 InstanceType* last) { |
| 1323 ASSERT(is_interval_check()); | 1316 ASSERT(is_interval_check()); |
| 1324 switch (check_) { | 1317 switch (check_) { |
| 1325 case IS_SPEC_OBJECT: | 1318 case IS_SPEC_OBJECT: |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 } | 1800 } |
| 1808 | 1801 |
| 1809 | 1802 |
| 1810 static bool IsInteger32(double value) { | 1803 static bool IsInteger32(double value) { |
| 1811 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 1804 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
| 1812 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 1805 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
| 1813 } | 1806 } |
| 1814 | 1807 |
| 1815 | 1808 |
| 1816 HConstant::HConstant(Handle<Object> handle, Representation r) | 1809 HConstant::HConstant(Handle<Object> handle, Representation r) |
| 1817 : handle_(handle), | 1810 : handle_(handle), |
| 1818 has_int32_value_(false), | 1811 has_int32_value_(false), |
| 1819 has_double_value_(false) { | 1812 has_double_value_(false), |
| 1820 // Dereferencing here is safe: the value of a number object does not change. | 1813 is_internalized_string_(false), |
| 1821 AllowHandleDereference allow_handle_deref(Isolate::Current()); | 1814 boolean_value_(handle->BooleanValue()) { |
| 1822 if (handle_->IsNumber()) { | 1815 if (handle_->IsNumber()) { |
| 1823 double n = handle_->Number(); | 1816 double n = handle_->Number(); |
| 1824 has_int32_value_ = IsInteger32(n); | 1817 has_int32_value_ = IsInteger32(n); |
| 1825 int32_value_ = DoubleToInt32(n); | 1818 int32_value_ = DoubleToInt32(n); |
| 1826 double_value_ = n; | 1819 double_value_ = n; |
| 1827 has_double_value_ = true; | 1820 has_double_value_ = true; |
| 1821 } else { |
| 1822 type_from_value_ = HType::TypeFromValue(handle_); |
| 1823 is_internalized_string_ = handle_->IsInternalizedString(); |
| 1828 } | 1824 } |
| 1829 if (r.IsNone()) { | 1825 if (r.IsNone()) { |
| 1830 if (has_int32_value_) { | 1826 if (has_int32_value_) { |
| 1831 r = Representation::Integer32(); | 1827 r = Representation::Integer32(); |
| 1832 } else if (has_double_value_) { | 1828 } else if (has_double_value_) { |
| 1833 r = Representation::Double(); | 1829 r = Representation::Double(); |
| 1834 } else { | 1830 } else { |
| 1835 r = Representation::Tagged(); | 1831 r = Representation::Tagged(); |
| 1836 } | 1832 } |
| 1837 } | 1833 } |
| 1838 Initialize(r); | 1834 Initialize(r); |
| 1839 } | 1835 } |
| 1840 | 1836 |
| 1841 | 1837 |
| 1842 HConstant::HConstant(int32_t integer_value, Representation r) | 1838 HConstant::HConstant(Handle<Object> handle, |
| 1839 Representation r, |
| 1840 HType type, |
| 1841 bool is_internalize_string, |
| 1842 bool boolean_value) |
| 1843 : handle_(handle), |
| 1844 has_int32_value_(false), |
| 1845 has_double_value_(false), |
| 1846 is_internalized_string_(is_internalize_string), |
| 1847 boolean_value_(boolean_value), |
| 1848 type_from_value_(type) { |
| 1849 ASSERT(!handle.is_null()); |
| 1850 ASSERT(!type.IsUninitialized()); |
| 1851 ASSERT(!type.IsTaggedNumber()); |
| 1852 Initialize(r); |
| 1853 } |
| 1854 |
| 1855 |
| 1856 HConstant::HConstant(int32_t integer_value, |
| 1857 Representation r, |
| 1858 Handle<Object> optional_handle) |
| 1843 : has_int32_value_(true), | 1859 : has_int32_value_(true), |
| 1844 has_double_value_(true), | 1860 has_double_value_(true), |
| 1861 is_internalized_string_(false), |
| 1862 boolean_value_(integer_value != 0), |
| 1845 int32_value_(integer_value), | 1863 int32_value_(integer_value), |
| 1846 double_value_(FastI2D(integer_value)) { | 1864 double_value_(FastI2D(integer_value)) { |
| 1847 Initialize(r); | 1865 Initialize(r); |
| 1848 } | 1866 } |
| 1849 | 1867 |
| 1850 | 1868 |
| 1851 HConstant::HConstant(double double_value, Representation r) | 1869 HConstant::HConstant(double double_value, |
| 1870 Representation r, |
| 1871 Handle<Object> optional_handle) |
| 1852 : has_int32_value_(IsInteger32(double_value)), | 1872 : has_int32_value_(IsInteger32(double_value)), |
| 1853 has_double_value_(true), | 1873 has_double_value_(true), |
| 1874 is_internalized_string_(false), |
| 1875 boolean_value_(double_value != 0 && !isnan(double_value)), |
| 1854 int32_value_(DoubleToInt32(double_value)), | 1876 int32_value_(DoubleToInt32(double_value)), |
| 1855 double_value_(double_value) { | 1877 double_value_(double_value) { |
| 1856 Initialize(r); | 1878 Initialize(r); |
| 1857 } | 1879 } |
| 1858 | 1880 |
| 1859 | 1881 |
| 1860 void HConstant::Initialize(Representation r) { | 1882 void HConstant::Initialize(Representation r) { |
| 1861 set_representation(r); | 1883 set_representation(r); |
| 1862 SetFlag(kUseGVN); | 1884 SetFlag(kUseGVN); |
| 1863 if (representation().IsInteger32()) { | 1885 if (representation().IsInteger32()) { |
| 1864 ClearGVNFlag(kDependsOnOsrEntries); | 1886 ClearGVNFlag(kDependsOnOsrEntries); |
| 1865 } | 1887 } |
| 1866 } | 1888 } |
| 1867 | 1889 |
| 1868 | 1890 |
| 1869 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 1891 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
| 1870 if (r.IsInteger32() && !has_int32_value_) return NULL; | 1892 if (r.IsInteger32() && !has_int32_value_) return NULL; |
| 1871 if (r.IsDouble() && !has_double_value_) return NULL; | 1893 if (r.IsDouble() && !has_double_value_) return NULL; |
| 1872 if (handle_.is_null()) { | 1894 if (has_int32_value_) return new(zone) HConstant(int32_value_, r, handle_); |
| 1873 ASSERT(has_int32_value_ || has_double_value_); | 1895 if (has_double_value_) return new(zone) HConstant(double_value_, r, handle_); |
| 1874 if (has_int32_value_) return new(zone) HConstant(int32_value_, r); | 1896 ASSERT(!handle_.is_null()); |
| 1875 return new(zone) HConstant(double_value_, r); | 1897 return new(zone) HConstant( |
| 1876 } | 1898 handle_, r, type_from_value_, is_internalized_string_, boolean_value_); |
| 1877 return new(zone) HConstant(handle_, r); | |
| 1878 } | 1899 } |
| 1879 | 1900 |
| 1880 | 1901 |
| 1881 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { | 1902 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { |
| 1882 if (has_int32_value_) { | 1903 if (has_int32_value_) { |
| 1883 if (handle_.is_null()) { | 1904 return new(zone) HConstant( |
| 1884 return new(zone) HConstant(int32_value_, Representation::Integer32()); | 1905 int32_value_, Representation::Integer32(), handle_); |
| 1885 } else { | |
| 1886 // Re-use the existing Handle if possible. | |
| 1887 return new(zone) HConstant(handle_, Representation::Integer32()); | |
| 1888 } | |
| 1889 } else if (has_double_value_) { | |
| 1890 return new(zone) HConstant(DoubleToInt32(double_value_), | |
| 1891 Representation::Integer32()); | |
| 1892 } else { | |
| 1893 return NULL; | |
| 1894 } | 1906 } |
| 1907 if (has_double_value_) { |
| 1908 return new(zone) HConstant( |
| 1909 DoubleToInt32(double_value_), Representation::Integer32(), handle_); |
| 1910 } |
| 1911 return NULL; |
| 1895 } | 1912 } |
| 1896 | 1913 |
| 1897 | 1914 |
| 1898 bool HConstant::ToBoolean() { | |
| 1899 // Converts the constant's boolean value according to | |
| 1900 // ECMAScript section 9.2 ToBoolean conversion. | |
| 1901 if (HasInteger32Value()) return Integer32Value() != 0; | |
| 1902 if (HasDoubleValue()) { | |
| 1903 double v = DoubleValue(); | |
| 1904 return v != 0 && !isnan(v); | |
| 1905 } | |
| 1906 // Dereferencing is safe: singletons do not change and strings are | |
| 1907 // immutable. | |
| 1908 AllowHandleDereference allow_handle_deref(isolate()); | |
| 1909 if (handle_->IsTrue()) return true; | |
| 1910 if (handle_->IsFalse()) return false; | |
| 1911 if (handle_->IsUndefined()) return false; | |
| 1912 if (handle_->IsNull()) return false; | |
| 1913 if (handle_->IsString() && String::cast(*handle_)->length() == 0) { | |
| 1914 return false; | |
| 1915 } | |
| 1916 return true; | |
| 1917 } | |
| 1918 | |
| 1919 void HConstant::PrintDataTo(StringStream* stream) { | 1915 void HConstant::PrintDataTo(StringStream* stream) { |
| 1920 if (has_int32_value_) { | 1916 if (has_int32_value_) { |
| 1921 stream->Add("%d ", int32_value_); | 1917 stream->Add("%d ", int32_value_); |
| 1922 } else if (has_double_value_) { | 1918 } else if (has_double_value_) { |
| 1923 stream->Add("%f ", FmtElm(double_value_)); | 1919 stream->Add("%f ", FmtElm(double_value_)); |
| 1924 } else { | 1920 } else { |
| 1925 handle()->ShortPrint(stream); | 1921 handle()->ShortPrint(stream); |
| 1926 } | 1922 } |
| 1927 } | 1923 } |
| 1928 | 1924 |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2593 } | 2589 } |
| 2594 return result; | 2590 return result; |
| 2595 } | 2591 } |
| 2596 | 2592 |
| 2597 | 2593 |
| 2598 HType HConstant::CalculateInferredType() { | 2594 HType HConstant::CalculateInferredType() { |
| 2599 if (has_int32_value_) { | 2595 if (has_int32_value_) { |
| 2600 return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber(); | 2596 return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber(); |
| 2601 } | 2597 } |
| 2602 if (has_double_value_) return HType::HeapNumber(); | 2598 if (has_double_value_) return HType::HeapNumber(); |
| 2603 return HType::TypeFromValue(isolate(), handle_); | 2599 ASSERT(!type_from_value_.IsUninitialized()); |
| 2600 return type_from_value_; |
| 2604 } | 2601 } |
| 2605 | 2602 |
| 2606 | 2603 |
| 2607 HType HCompareGeneric::CalculateInferredType() { | 2604 HType HCompareGeneric::CalculateInferredType() { |
| 2608 return HType::Boolean(); | 2605 return HType::Boolean(); |
| 2609 } | 2606 } |
| 2610 | 2607 |
| 2611 | 2608 |
| 2612 HType HInstanceOf::CalculateInferredType() { | 2609 HType HInstanceOf::CalculateInferredType() { |
| 2613 return HType::Boolean(); | 2610 return HType::Boolean(); |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3281 | 3278 |
| 3282 | 3279 |
| 3283 void HCheckFunction::Verify() { | 3280 void HCheckFunction::Verify() { |
| 3284 HInstruction::Verify(); | 3281 HInstruction::Verify(); |
| 3285 ASSERT(HasNoUses()); | 3282 ASSERT(HasNoUses()); |
| 3286 } | 3283 } |
| 3287 | 3284 |
| 3288 #endif | 3285 #endif |
| 3289 | 3286 |
| 3290 } } // namespace v8::internal | 3287 } } // namespace v8::internal |
| OLD | NEW |