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 5912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5923 | 5923 |
5924 | 5924 |
5925 i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate, | 5925 i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate, |
5926 v8::String::ExternalAsciiStringResource* resource) { | 5926 v8::String::ExternalAsciiStringResource* resource) { |
5927 i::Handle<i::String> result = | 5927 i::Handle<i::String> result = |
5928 isolate->factory()->NewExternalStringFromAscii(resource); | 5928 isolate->factory()->NewExternalStringFromAscii(resource); |
5929 return result; | 5929 return result; |
5930 } | 5930 } |
5931 | 5931 |
5932 | 5932 |
| 5933 bool RedirectToExternalString(i::Isolate* isolate, |
| 5934 i::Handle<i::String> parent, |
| 5935 i::Handle<i::String> external) { |
| 5936 if (parent->IsConsString()) { |
| 5937 i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent); |
| 5938 cons->set_first(*external); |
| 5939 cons->set_second(isolate->heap()->empty_string()); |
| 5940 } else { |
| 5941 ASSERT(parent->IsSlicedString()); |
| 5942 i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent); |
| 5943 slice->set_parent(*external); |
| 5944 slice->set_offset(0); |
| 5945 } |
| 5946 return true; |
| 5947 } |
| 5948 |
| 5949 |
5933 Local<String> v8::String::NewExternal( | 5950 Local<String> v8::String::NewExternal( |
5934 v8::String::ExternalStringResource* resource) { | 5951 v8::String::ExternalStringResource* resource) { |
5935 i::Isolate* isolate = i::Isolate::Current(); | 5952 i::Isolate* isolate = i::Isolate::Current(); |
5936 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); | 5953 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); |
5937 LOG_API(isolate, "String::NewExternal"); | 5954 LOG_API(isolate, "String::NewExternal"); |
5938 ENTER_V8(isolate); | 5955 ENTER_V8(isolate); |
5939 CHECK(resource && resource->data()); | 5956 CHECK(resource && resource->data()); |
5940 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource); | 5957 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource); |
5941 isolate->heap()->external_string_table()->AddString(*result); | 5958 isolate->heap()->external_string_table()->AddString(*result); |
5942 return Utils::ToLocal(result); | 5959 return Utils::ToLocal(result); |
5943 } | 5960 } |
5944 | 5961 |
5945 | 5962 |
5946 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { | 5963 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { |
5947 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5964 i::Handle<i::String> obj = Utils::OpenHandle(this); |
5948 i::Isolate* isolate = obj->GetIsolate(); | 5965 i::Isolate* isolate = obj->GetIsolate(); |
5949 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false; | 5966 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false; |
5950 if (i::StringShape(*obj).IsExternalTwoByte()) { | 5967 if (i::StringShape(*obj).IsExternalTwoByte()) { |
5951 return false; // Already an external string. | 5968 return false; // Already an external string. |
5952 } | 5969 } |
5953 ENTER_V8(isolate); | 5970 ENTER_V8(isolate); |
5954 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5971 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5955 return false; | 5972 return false; |
5956 } | 5973 } |
5957 if (isolate->heap()->IsInGCPostProcessing()) { | 5974 if (isolate->heap()->IsInGCPostProcessing()) { |
5958 return false; | 5975 return false; |
5959 } | 5976 } |
5960 CHECK(resource && resource->data()); | 5977 CHECK(resource && resource->data()); |
5961 bool result = obj->MakeExternal(resource); | 5978 |
5962 if (result && !obj->IsInternalizedString()) { | 5979 bool result; |
5963 isolate->heap()->external_string_table()->AddString(*obj); | 5980 i::Handle<i::String> external; |
| 5981 if (isolate->heap()->old_pointer_space()->Contains(*obj)) { |
| 5982 // We do not allow external strings in the old pointer space. Instead of |
| 5983 // converting the string in-place, we keep the cons/sliced string and |
| 5984 // point it to a newly-allocated external string. |
| 5985 external = NewExternalStringHandle(isolate, resource); |
| 5986 result = RedirectToExternalString(isolate, obj, external); |
| 5987 } else { |
| 5988 result = obj->MakeExternal(resource); |
| 5989 external = obj; |
| 5990 } |
| 5991 |
| 5992 ASSERT(external->IsExternalString()); |
| 5993 if (result && !external->IsInternalizedString()) { |
| 5994 isolate->heap()->external_string_table()->AddString(*external); |
5964 } | 5995 } |
5965 return result; | 5996 return result; |
5966 } | 5997 } |
5967 | 5998 |
5968 | 5999 |
5969 Local<String> v8::String::NewExternal( | 6000 Local<String> v8::String::NewExternal( |
5970 v8::String::ExternalAsciiStringResource* resource) { | 6001 v8::String::ExternalAsciiStringResource* resource) { |
5971 i::Isolate* isolate = i::Isolate::Current(); | 6002 i::Isolate* isolate = i::Isolate::Current(); |
5972 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); | 6003 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); |
5973 LOG_API(isolate, "String::NewExternal"); | 6004 LOG_API(isolate, "String::NewExternal"); |
(...skipping 14 matching lines...) Expand all Loading... |
5988 return false; // Already an external string. | 6019 return false; // Already an external string. |
5989 } | 6020 } |
5990 ENTER_V8(isolate); | 6021 ENTER_V8(isolate); |
5991 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 6022 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5992 return false; | 6023 return false; |
5993 } | 6024 } |
5994 if (isolate->heap()->IsInGCPostProcessing()) { | 6025 if (isolate->heap()->IsInGCPostProcessing()) { |
5995 return false; | 6026 return false; |
5996 } | 6027 } |
5997 CHECK(resource && resource->data()); | 6028 CHECK(resource && resource->data()); |
5998 bool result = obj->MakeExternal(resource); | 6029 |
5999 if (result && !obj->IsInternalizedString()) { | 6030 bool result; |
6000 isolate->heap()->external_string_table()->AddString(*obj); | 6031 i::Handle<i::String> external; |
| 6032 if (isolate->heap()->old_pointer_space()->Contains(*obj)) { |
| 6033 // We do not allow external strings in the old pointer space. Instead of |
| 6034 // converting the string in-place, we keep the cons/sliced string and |
| 6035 // point it to a newly-allocated external string. |
| 6036 external = NewExternalAsciiStringHandle(isolate, resource); |
| 6037 result = RedirectToExternalString(isolate, obj, external); |
| 6038 } else { |
| 6039 result = obj->MakeExternal(resource); |
| 6040 external = obj; |
| 6041 } |
| 6042 |
| 6043 ASSERT(external->IsExternalString()); |
| 6044 if (result && !external->IsInternalizedString()) { |
| 6045 isolate->heap()->external_string_table()->AddString(*external); |
6001 } | 6046 } |
6002 return result; | 6047 return result; |
6003 } | 6048 } |
6004 | 6049 |
6005 | 6050 |
6006 bool v8::String::CanMakeExternal() { | 6051 bool v8::String::CanMakeExternal() { |
6007 if (!internal::FLAG_clever_optimizations) return false; | 6052 if (!internal::FLAG_clever_optimizations) return false; |
6008 i::Handle<i::String> obj = Utils::OpenHandle(this); | 6053 i::Handle<i::String> obj = Utils::OpenHandle(this); |
6009 i::Isolate* isolate = obj->GetIsolate(); | 6054 i::Isolate* isolate = obj->GetIsolate(); |
6010 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false; | 6055 if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false; |
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8052 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 8097 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
8053 Address callback_address = | 8098 Address callback_address = |
8054 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 8099 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
8055 VMState<EXTERNAL> state(isolate); | 8100 VMState<EXTERNAL> state(isolate); |
8056 ExternalCallbackScope call_scope(isolate, callback_address); | 8101 ExternalCallbackScope call_scope(isolate, callback_address); |
8057 return callback(info); | 8102 return callback(info); |
8058 } | 8103 } |
8059 | 8104 |
8060 | 8105 |
8061 } } // namespace v8::internal | 8106 } } // namespace v8::internal |
OLD | NEW |