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 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(), | 763 if (!ApiCheck(isolate->handle_scope_implementer()->LeaveLastContext(), |
764 "v8::Context::Exit()", | 764 "v8::Context::Exit()", |
765 "Cannot exit non-entered context")) { | 765 "Cannot exit non-entered context")) { |
766 return; | 766 return; |
767 } | 767 } |
768 | 768 |
769 // Content of 'last_context' could be NULL. | 769 // Content of 'last_context' could be NULL. |
770 i::Context* last_context = | 770 i::Context* last_context = |
771 isolate->handle_scope_implementer()->RestoreContext(); | 771 isolate->handle_scope_implementer()->RestoreContext(); |
772 isolate->set_context(last_context); | 772 isolate->set_context(last_context); |
773 isolate->set_context_exit_happened(true); | |
774 } | 773 } |
775 | 774 |
776 | 775 |
777 static void* DecodeSmiToAligned(i::Object* value, const char* location) { | 776 static void* DecodeSmiToAligned(i::Object* value, const char* location) { |
778 ApiCheck(value->IsSmi(), location, "Not a Smi"); | 777 ApiCheck(value->IsSmi(), location, "Not a Smi"); |
779 return reinterpret_cast<void*>(value); | 778 return reinterpret_cast<void*>(value); |
780 } | 779 } |
781 | 780 |
782 | 781 |
783 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { | 782 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { |
(...skipping 5140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5924 | 5923 |
5925 | 5924 |
5926 i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate, | 5925 i::Handle<i::String> NewExternalAsciiStringHandle(i::Isolate* isolate, |
5927 v8::String::ExternalAsciiStringResource* resource) { | 5926 v8::String::ExternalAsciiStringResource* resource) { |
5928 i::Handle<i::String> result = | 5927 i::Handle<i::String> result = |
5929 isolate->factory()->NewExternalStringFromAscii(resource); | 5928 isolate->factory()->NewExternalStringFromAscii(resource); |
5930 return result; | 5929 return result; |
5931 } | 5930 } |
5932 | 5931 |
5933 | 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 |
5934 Local<String> v8::String::NewExternal( | 5950 Local<String> v8::String::NewExternal( |
5935 v8::String::ExternalStringResource* resource) { | 5951 v8::String::ExternalStringResource* resource) { |
5936 i::Isolate* isolate = i::Isolate::Current(); | 5952 i::Isolate* isolate = i::Isolate::Current(); |
5937 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); | 5953 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); |
5938 LOG_API(isolate, "String::NewExternal"); | 5954 LOG_API(isolate, "String::NewExternal"); |
5939 ENTER_V8(isolate); | 5955 ENTER_V8(isolate); |
5940 CHECK(resource && resource->data()); | 5956 CHECK(resource && resource->data()); |
5941 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource); | 5957 i::Handle<i::String> result = NewExternalStringHandle(isolate, resource); |
5942 isolate->heap()->external_string_table()->AddString(*result); | 5958 isolate->heap()->external_string_table()->AddString(*result); |
5943 return Utils::ToLocal(result); | 5959 return Utils::ToLocal(result); |
5944 } | 5960 } |
5945 | 5961 |
5946 | 5962 |
5947 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { | 5963 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { |
5948 i::Handle<i::String> obj = Utils::OpenHandle(this); | 5964 i::Handle<i::String> obj = Utils::OpenHandle(this); |
5949 i::Isolate* isolate = obj->GetIsolate(); | 5965 i::Isolate* isolate = obj->GetIsolate(); |
5950 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false; | 5966 if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false; |
5951 if (i::StringShape(*obj).IsExternalTwoByte()) { | 5967 if (i::StringShape(*obj).IsExternalTwoByte()) { |
5952 return false; // Already an external string. | 5968 return false; // Already an external string. |
5953 } | 5969 } |
5954 ENTER_V8(isolate); | 5970 ENTER_V8(isolate); |
5955 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 5971 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5956 return false; | 5972 return false; |
5957 } | 5973 } |
5958 if (isolate->heap()->IsInGCPostProcessing()) { | 5974 if (isolate->heap()->IsInGCPostProcessing()) { |
5959 return false; | 5975 return false; |
5960 } | 5976 } |
5961 CHECK(resource && resource->data()); | 5977 CHECK(resource && resource->data()); |
5962 bool result = obj->MakeExternal(resource); | 5978 |
5963 if (result && !obj->IsInternalizedString()) { | 5979 bool result; |
5964 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); |
5965 } | 5995 } |
5966 return result; | 5996 return result; |
5967 } | 5997 } |
5968 | 5998 |
5969 | 5999 |
5970 Local<String> v8::String::NewExternal( | 6000 Local<String> v8::String::NewExternal( |
5971 v8::String::ExternalAsciiStringResource* resource) { | 6001 v8::String::ExternalAsciiStringResource* resource) { |
5972 i::Isolate* isolate = i::Isolate::Current(); | 6002 i::Isolate* isolate = i::Isolate::Current(); |
5973 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); | 6003 EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()"); |
5974 LOG_API(isolate, "String::NewExternal"); | 6004 LOG_API(isolate, "String::NewExternal"); |
(...skipping 14 matching lines...) Expand all Loading... |
5989 return false; // Already an external string. | 6019 return false; // Already an external string. |
5990 } | 6020 } |
5991 ENTER_V8(isolate); | 6021 ENTER_V8(isolate); |
5992 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { | 6022 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { |
5993 return false; | 6023 return false; |
5994 } | 6024 } |
5995 if (isolate->heap()->IsInGCPostProcessing()) { | 6025 if (isolate->heap()->IsInGCPostProcessing()) { |
5996 return false; | 6026 return false; |
5997 } | 6027 } |
5998 CHECK(resource && resource->data()); | 6028 CHECK(resource && resource->data()); |
5999 bool result = obj->MakeExternal(resource); | 6029 |
6000 if (result && !obj->IsInternalizedString()) { | 6030 bool result; |
6001 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); |
6002 } | 6046 } |
6003 return result; | 6047 return result; |
6004 } | 6048 } |
6005 | 6049 |
6006 | 6050 |
6007 bool v8::String::CanMakeExternal() { | 6051 bool v8::String::CanMakeExternal() { |
6008 if (!internal::FLAG_clever_optimizations) return false; | 6052 if (!internal::FLAG_clever_optimizations) return false; |
6009 i::Handle<i::String> obj = Utils::OpenHandle(this); | 6053 i::Handle<i::String> obj = Utils::OpenHandle(this); |
6010 i::Isolate* isolate = obj->GetIsolate(); | 6054 i::Isolate* isolate = obj->GetIsolate(); |
6011 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... |
8053 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 8097 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
8054 Address callback_address = | 8098 Address callback_address = |
8055 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 8099 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
8056 VMState<EXTERNAL> state(isolate); | 8100 VMState<EXTERNAL> state(isolate); |
8057 ExternalCallbackScope call_scope(isolate, callback_address); | 8101 ExternalCallbackScope call_scope(isolate, callback_address); |
8058 return callback(info); | 8102 return callback(info); |
8059 } | 8103 } |
8060 | 8104 |
8061 | 8105 |
8062 } } // namespace v8::internal | 8106 } } // namespace v8::internal |
OLD | NEW |