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 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 // Due to some WebKit tests, we want to make sure that we do not log | 1091 // Due to some WebKit tests, we want to make sure that we do not log |
1092 // more than one access failure here. | 1092 // more than one access failure here. |
1093 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { | 1093 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { |
1094 case ACCESS_FORBIDDEN: return heap->false_value(); | 1094 case ACCESS_FORBIDDEN: return heap->false_value(); |
1095 case ACCESS_ALLOWED: break; | 1095 case ACCESS_ALLOWED: break; |
1096 case ACCESS_ABSENT: return heap->undefined_value(); | 1096 case ACCESS_ABSENT: return heap->undefined_value(); |
1097 } | 1097 } |
1098 | 1098 |
1099 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); | 1099 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
1100 if (attrs == ABSENT) return heap->undefined_value(); | 1100 if (attrs == ABSENT) return heap->undefined_value(); |
1101 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); | 1101 AccessorPair* accessors = obj->GetLocalPropertyAccessorPair(*name); |
1102 Handle<AccessorPair> accessors(raw_accessors, isolate); | |
1103 | 1102 |
1104 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1103 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
1105 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1104 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
1106 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1105 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
1107 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); | 1106 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(accessors != NULL)); |
1108 | 1107 |
1109 if (raw_accessors == NULL) { | 1108 if (accessors == NULL) { |
1110 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); | 1109 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
1111 // GetProperty does access check. | 1110 // GetProperty does access check. |
1112 Handle<Object> value = GetProperty(obj, name); | 1111 Handle<Object> value = GetProperty(obj, name); |
1113 if (value.is_null()) return Failure::Exception(); | 1112 if (value.is_null()) return Failure::Exception(); |
1114 elms->set(VALUE_INDEX, *value); | 1113 elms->set(VALUE_INDEX, *value); |
1115 } else { | 1114 } else { |
1116 // Access checks are performed for both accessors separately. | 1115 // Access checks are performed for both accessors separately. |
1117 // When they fail, the respective field is not set in the descriptor. | 1116 // When they fail, the respective field is not set in the descriptor. |
1118 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1117 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
1119 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); | 1118 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); |
(...skipping 4677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5797 // become garbage; there is no reason to keep two identical strings | 5796 // become garbage; there is no reason to keep two identical strings |
5798 // alive. | 5797 // alive. |
5799 return s; | 5798 return s; |
5800 } | 5799 } |
5801 } | 5800 } |
5802 | 5801 |
5803 | 5802 |
5804 namespace { | 5803 namespace { |
5805 | 5804 |
5806 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; | 5805 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; |
5807 #ifdef ENABLE_LATIN_1 | 5806 |
5808 static const uintptr_t kAsciiMask = kOneInEveryByte << 7; | |
5809 #endif | |
5810 | 5807 |
5811 // Given a word and two range boundaries returns a word with high bit | 5808 // Given a word and two range boundaries returns a word with high bit |
5812 // set in every byte iff the corresponding input byte was strictly in | 5809 // set in every byte iff the corresponding input byte was strictly in |
5813 // the range (m, n). All the other bits in the result are cleared. | 5810 // the range (m, n). All the other bits in the result are cleared. |
5814 // This function is only useful when it can be inlined and the | 5811 // This function is only useful when it can be inlined and the |
5815 // boundaries are statically known. | 5812 // boundaries are statically known. |
5816 // Requires: all bytes in the input word and the boundaries must be | 5813 // Requires: all bytes in the input word and the boundaries must be |
5817 // ASCII (less than 0x7F). | 5814 // ASCII (less than 0x7F). |
5818 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { | 5815 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { |
5819 // Every byte in an ASCII string is less than or equal to 0x7F. | 5816 // Every byte in an ASCII string is less than or equal to 0x7F. |
5820 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); | 5817 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); |
5821 // Use strict inequalities since in edge cases the function could be | 5818 // Use strict inequalities since in edge cases the function could be |
5822 // further simplified. | 5819 // further simplified. |
5823 ASSERT(0 < m && m < n); | 5820 ASSERT(0 < m && m < n && n < 0x7F); |
5824 #ifndef ENABLE_LATIN_1 | |
5825 ASSERT(n < 0x7F); | |
5826 #endif | |
5827 // Has high bit set in every w byte less than n. | 5821 // Has high bit set in every w byte less than n. |
5828 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; | 5822 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; |
5829 // Has high bit set in every w byte greater than m. | 5823 // Has high bit set in every w byte greater than m. |
5830 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); | 5824 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); |
5831 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); | 5825 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); |
5832 } | 5826 } |
5833 | 5827 |
5834 | 5828 |
5835 enum AsciiCaseConversion { | 5829 enum AsciiCaseConversion { |
5836 ASCII_TO_LOWER, | 5830 ASCII_TO_LOWER, |
5837 ASCII_TO_UPPER | 5831 ASCII_TO_UPPER |
5838 }; | 5832 }; |
5839 | 5833 |
5840 | 5834 |
5841 template <AsciiCaseConversion dir> | 5835 template <AsciiCaseConversion dir> |
5842 struct FastAsciiConverter { | 5836 struct FastAsciiConverter { |
5843 #ifdef ENABLE_LATIN_1 | |
5844 static bool Convert(char* dst, char* src, int length, bool* changed_out) { | |
5845 #else | |
5846 static bool Convert(char* dst, char* src, int length) { | 5837 static bool Convert(char* dst, char* src, int length) { |
5847 #endif | |
5848 #ifdef DEBUG | 5838 #ifdef DEBUG |
5849 char* saved_dst = dst; | 5839 char* saved_dst = dst; |
5850 char* saved_src = src; | 5840 char* saved_src = src; |
5851 #endif | 5841 #endif |
5852 // We rely on the distance between upper and lower case letters | 5842 // We rely on the distance between upper and lower case letters |
5853 // being a known power of 2. | 5843 // being a known power of 2. |
5854 ASSERT('a' - 'A' == (1 << 5)); | 5844 ASSERT('a' - 'A' == (1 << 5)); |
5855 // Boundaries for the range of input characters than require conversion. | 5845 // Boundaries for the range of input characters than require conversion. |
5856 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; | 5846 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; |
5857 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; | 5847 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; |
5858 bool changed = false; | 5848 bool changed = false; |
5859 #ifdef ENABLE_LATIN_1 | |
5860 uintptr_t or_acc = 0; | |
5861 #endif | |
5862 char* const limit = src + length; | 5849 char* const limit = src + length; |
5863 #ifdef V8_HOST_CAN_READ_UNALIGNED | 5850 #ifdef V8_HOST_CAN_READ_UNALIGNED |
5864 // Process the prefix of the input that requires no conversion one | 5851 // Process the prefix of the input that requires no conversion one |
5865 // (machine) word at a time. | 5852 // (machine) word at a time. |
5866 while (src <= limit - sizeof(uintptr_t)) { | 5853 while (src <= limit - sizeof(uintptr_t)) { |
5867 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); | 5854 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
5868 #ifdef ENABLE_LATIN_1 | |
5869 or_acc |= w; | |
5870 #endif | |
5871 if (AsciiRangeMask(w, lo, hi) != 0) { | 5855 if (AsciiRangeMask(w, lo, hi) != 0) { |
5872 changed = true; | 5856 changed = true; |
5873 break; | 5857 break; |
5874 } | 5858 } |
5875 *reinterpret_cast<uintptr_t*>(dst) = w; | 5859 *reinterpret_cast<uintptr_t*>(dst) = w; |
5876 src += sizeof(uintptr_t); | 5860 src += sizeof(uintptr_t); |
5877 dst += sizeof(uintptr_t); | 5861 dst += sizeof(uintptr_t); |
5878 } | 5862 } |
5879 // Process the remainder of the input performing conversion when | 5863 // Process the remainder of the input performing conversion when |
5880 // required one word at a time. | 5864 // required one word at a time. |
5881 while (src <= limit - sizeof(uintptr_t)) { | 5865 while (src <= limit - sizeof(uintptr_t)) { |
5882 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); | 5866 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
5883 #ifdef ENABLE_LATIN_1 | |
5884 or_acc |= w; | |
5885 #endif | |
5886 uintptr_t m = AsciiRangeMask(w, lo, hi); | 5867 uintptr_t m = AsciiRangeMask(w, lo, hi); |
5887 // The mask has high (7th) bit set in every byte that needs | 5868 // The mask has high (7th) bit set in every byte that needs |
5888 // conversion and we know that the distance between cases is | 5869 // conversion and we know that the distance between cases is |
5889 // 1 << 5. | 5870 // 1 << 5. |
5890 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); | 5871 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); |
5891 src += sizeof(uintptr_t); | 5872 src += sizeof(uintptr_t); |
5892 dst += sizeof(uintptr_t); | 5873 dst += sizeof(uintptr_t); |
5893 } | 5874 } |
5894 #endif | 5875 #endif |
5895 // Process the last few bytes of the input (or the whole input if | 5876 // Process the last few bytes of the input (or the whole input if |
5896 // unaligned access is not supported). | 5877 // unaligned access is not supported). |
5897 while (src < limit) { | 5878 while (src < limit) { |
5898 char c = *src; | 5879 char c = *src; |
5899 #ifdef ENABLE_LATIN_1 | |
5900 or_acc |= c; | |
5901 #endif | |
5902 if (lo < c && c < hi) { | 5880 if (lo < c && c < hi) { |
5903 c ^= (1 << 5); | 5881 c ^= (1 << 5); |
5904 changed = true; | 5882 changed = true; |
5905 } | 5883 } |
5906 *dst = c; | 5884 *dst = c; |
5907 ++src; | 5885 ++src; |
5908 ++dst; | 5886 ++dst; |
5909 } | 5887 } |
5910 #ifdef ENABLE_LATIN_1 | |
5911 if ((or_acc & kAsciiMask) != 0) { | |
5912 return false; | |
5913 } | |
5914 #endif | |
5915 #ifdef DEBUG | 5888 #ifdef DEBUG |
5916 CheckConvert(saved_dst, saved_src, length, changed); | 5889 CheckConvert(saved_dst, saved_src, length, changed); |
5917 #endif | 5890 #endif |
5918 #ifdef ENABLE_LATIN_1 | |
5919 *changed_out = changed; | |
5920 return true; | |
5921 #else | |
5922 return changed; | 5891 return changed; |
5923 #endif | |
5924 } | 5892 } |
5925 | 5893 |
5926 #ifdef DEBUG | 5894 #ifdef DEBUG |
5927 static void CheckConvert(char* dst, char* src, int length, bool changed) { | 5895 static void CheckConvert(char* dst, char* src, int length, bool changed) { |
5928 bool expected_changed = false; | 5896 bool expected_changed = false; |
5929 for (int i = 0; i < length; i++) { | 5897 for (int i = 0; i < length; i++) { |
5930 if (dst[i] == src[i]) continue; | 5898 if (dst[i] == src[i]) continue; |
5931 expected_changed = true; | 5899 expected_changed = true; |
5932 if (dir == ASCII_TO_LOWER) { | 5900 if (dir == ASCII_TO_LOWER) { |
5933 ASSERT('A' <= src[i] && src[i] <= 'Z'); | 5901 ASSERT('A' <= src[i] && src[i] <= 'Z'); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5966 Isolate* isolate, | 5934 Isolate* isolate, |
5967 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 5935 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
5968 NoHandleAllocation ha; | 5936 NoHandleAllocation ha; |
5969 CONVERT_ARG_CHECKED(String, s, 0); | 5937 CONVERT_ARG_CHECKED(String, s, 0); |
5970 s = s->TryFlattenGetString(); | 5938 s = s->TryFlattenGetString(); |
5971 | 5939 |
5972 const int length = s->length(); | 5940 const int length = s->length(); |
5973 // Assume that the string is not empty; we need this assumption later | 5941 // Assume that the string is not empty; we need this assumption later |
5974 if (length == 0) return s; | 5942 if (length == 0) return s; |
5975 | 5943 |
| 5944 #ifndef ENABLE_LATIN_1 |
5976 // Simpler handling of ASCII strings. | 5945 // Simpler handling of ASCII strings. |
5977 // | 5946 // |
5978 // NOTE: This assumes that the upper/lower case of an ASCII | 5947 // NOTE: This assumes that the upper/lower case of an ASCII |
5979 // character is also ASCII. This is currently the case, but it | 5948 // character is also ASCII. This is currently the case, but it |
5980 // might break in the future if we implement more context and locale | 5949 // might break in the future if we implement more context and locale |
5981 // dependent upper/lower conversions. | 5950 // dependent upper/lower conversions. |
5982 if (s->IsSeqOneByteString()) { | 5951 if (s->IsSeqOneByteString()) { |
5983 Object* o; | 5952 Object* o; |
5984 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); | 5953 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); |
5985 if (!maybe_o->ToObject(&o)) return maybe_o; | 5954 if (!maybe_o->ToObject(&o)) return maybe_o; |
5986 } | 5955 } |
5987 SeqOneByteString* result = SeqOneByteString::cast(o); | 5956 SeqOneByteString* result = SeqOneByteString::cast(o); |
5988 #ifndef ENABLE_LATIN_1 | |
5989 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 5957 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
5990 reinterpret_cast<char*>(result->GetChars()), | 5958 reinterpret_cast<char*>(result->GetChars()), |
5991 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), | 5959 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), |
5992 length); | 5960 length); |
5993 return has_changed_character ? result : s; | 5961 return has_changed_character ? result : s; |
5994 #else | 5962 } |
5995 bool has_changed_character; | |
5996 bool is_ascii = ConvertTraits::AsciiConverter::Convert( | |
5997 reinterpret_cast<char*>(result->GetChars()), | |
5998 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), | |
5999 length, | |
6000 &has_changed_character); | |
6001 // If not ASCII, we discard the result and take the 2 byte path. | |
6002 if (is_ascii) { | |
6003 return has_changed_character ? result : s; | |
6004 } | |
6005 #endif | 5963 #endif |
6006 } | |
6007 | 5964 |
6008 Object* answer; | 5965 Object* answer; |
6009 { MaybeObject* maybe_answer = | 5966 { MaybeObject* maybe_answer = |
6010 ConvertCaseHelper(isolate, s, length, length, mapping); | 5967 ConvertCaseHelper(isolate, s, length, length, mapping); |
6011 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 5968 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
6012 } | 5969 } |
6013 if (answer->IsSmi()) { | 5970 if (answer->IsSmi()) { |
6014 // Retry with correct length. | 5971 // Retry with correct length. |
6015 { MaybeObject* maybe_answer = | 5972 { MaybeObject* maybe_answer = |
6016 ConvertCaseHelper(isolate, | 5973 ConvertCaseHelper(isolate, |
(...skipping 7238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13255 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); | 13212 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); |
13256 | 13213 |
13257 HandleScope scope(isolate); | 13214 HandleScope scope(isolate); |
13258 // Optionally capture a more detailed stack trace for the message. | 13215 // Optionally capture a more detailed stack trace for the message. |
13259 isolate->CaptureAndSetDetailedStackTrace(error_object); | 13216 isolate->CaptureAndSetDetailedStackTrace(error_object); |
13260 // Capture a simple stack trace for the stack property. | 13217 // Capture a simple stack trace for the stack property. |
13261 return *isolate->CaptureSimpleStackTrace(error_object, caller, limit); | 13218 return *isolate->CaptureSimpleStackTrace(error_object, caller, limit); |
13262 } | 13219 } |
13263 | 13220 |
13264 | 13221 |
13265 // Mark a function to recognize when called after GC to format the stack trace. | 13222 // Retrieve the raw stack trace collected on stack overflow and delete |
13266 RUNTIME_FUNCTION(MaybeObject*, Runtime_MarkOneShotGetter) { | 13223 // it since it is used only once to avoid keeping it alive. |
13267 ASSERT_EQ(args.length(), 1); | 13224 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedRawStackTrace) { |
13268 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | |
13269 HandleScope scope(isolate); | |
13270 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); | |
13271 JSObject::SetHiddenProperty(fun, key, key); | |
13272 return *fun; | |
13273 } | |
13274 | |
13275 | |
13276 // Retrieve the stack trace. This could be the raw stack trace collected | |
13277 // on stack overflow or the already formatted stack trace string. | |
13278 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) { | |
13279 HandleScope scope(isolate); | |
13280 ASSERT_EQ(args.length(), 1); | 13225 ASSERT_EQ(args.length(), 1); |
13281 CONVERT_ARG_CHECKED(JSObject, error_object, 0); | 13226 CONVERT_ARG_CHECKED(JSObject, error_object, 0); |
13282 String* key = isolate->heap()->hidden_stack_trace_symbol(); | 13227 String* key = isolate->heap()->hidden_stack_trace_symbol(); |
13283 Object* result = error_object->GetHiddenProperty(key); | 13228 Object* result = error_object->GetHiddenProperty(key); |
13284 RUNTIME_ASSERT(result->IsJSArray() || | 13229 RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined()); |
13285 result->IsString() || | 13230 error_object->DeleteHiddenProperty(key); |
13286 result->IsUndefined()); | |
13287 return result; | 13231 return result; |
13288 } | 13232 } |
13289 | 13233 |
13290 | 13234 |
13291 // Set or clear the stack trace attached to an stack overflow error object. | |
13292 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) { | |
13293 HandleScope scope(isolate); | |
13294 ASSERT_EQ(args.length(), 2); | |
13295 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); | |
13296 CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1); | |
13297 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); | |
13298 if (value->IsUndefined()) { | |
13299 error_object->DeleteHiddenProperty(*key); | |
13300 } else { | |
13301 RUNTIME_ASSERT(value->IsString()); | |
13302 JSObject::SetHiddenProperty(error_object, key, value); | |
13303 } | |
13304 return *error_object; | |
13305 } | |
13306 | |
13307 | |
13308 // Returns V8 version as a string. | 13235 // Returns V8 version as a string. |
13309 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { | 13236 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { |
13310 ASSERT_EQ(args.length(), 0); | 13237 ASSERT_EQ(args.length(), 0); |
13311 | 13238 |
13312 NoHandleAllocation ha; | 13239 NoHandleAllocation ha; |
13313 | 13240 |
13314 const char* version_string = v8::V8::GetVersion(); | 13241 const char* version_string = v8::V8::GetVersion(); |
13315 | 13242 |
13316 return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string), | 13243 return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string), |
13317 NOT_TENURED); | 13244 NOT_TENURED); |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13716 // Handle last resort GC and make sure to allow future allocations | 13643 // Handle last resort GC and make sure to allow future allocations |
13717 // to grow the heap without causing GCs (if possible). | 13644 // to grow the heap without causing GCs (if possible). |
13718 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13645 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13719 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13646 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13720 "Runtime::PerformGC"); | 13647 "Runtime::PerformGC"); |
13721 } | 13648 } |
13722 } | 13649 } |
13723 | 13650 |
13724 | 13651 |
13725 } } // namespace v8::internal | 13652 } } // namespace v8::internal |
OLD | NEW |