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 |