Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: src/api.cc

Issue 1149563011: Verify a bit more about external strings (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/v8.h ('k') | src/heap/heap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/api.h" 5 #include "src/api.h"
6 6
7 #include <string.h> // For memcpy, strlen. 7 #include <string.h> // For memcpy, strlen.
8 #ifdef V8_USE_ADDRESS_SANITIZER 8 #ifdef V8_USE_ADDRESS_SANITIZER
9 #include <sanitizer/asan_interface.h> 9 #include <sanitizer/asan_interface.h>
10 #endif // V8_USE_ADDRESS_SANITIZER 10 #endif // V8_USE_ADDRESS_SANITIZER
(...skipping 5281 matching lines...) Expand 10 before | Expand all | Expand 10 after
5292 i::Handle<i::String> str = Utils::OpenHandle(this); 5292 i::Handle<i::String> str = Utils::OpenHandle(this);
5293 return i::StringShape(*str).IsExternalTwoByte(); 5293 return i::StringShape(*str).IsExternalTwoByte();
5294 } 5294 }
5295 5295
5296 5296
5297 bool v8::String::IsExternalOneByte() const { 5297 bool v8::String::IsExternalOneByte() const {
5298 i::Handle<i::String> str = Utils::OpenHandle(this); 5298 i::Handle<i::String> str = Utils::OpenHandle(this);
5299 return i::StringShape(*str).IsExternalOneByte(); 5299 return i::StringShape(*str).IsExternalOneByte();
5300 } 5300 }
5301 5301
5302 5302 void v8::String::VerifyExternalStringResourceBase(
5303 void v8::String::VerifyExternalStringResource( 5303 const v8::String::ExternalStringResourceBase* value,
5304 v8::String::ExternalStringResource* value) const { 5304 Encoding encoding) const {
5305 i::Handle<i::String> str = Utils::OpenHandle(this); 5305 i::Handle<i::String> str = Utils::OpenHandle(this);
5306 const v8::String::ExternalStringResource* expected; 5306 const v8::String::ExternalStringResourceBase* expected = nullptr;
5307 if (i::StringShape(*str).IsExternalTwoByte()) { 5307 Encoding expected_encoding;
5308 const void* resource = 5308 const void* actual_data_ptr = nullptr;
5309 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); 5309 size_t actual_length = 0;
5310 expected = reinterpret_cast<const ExternalStringResource*>(resource); 5310 if (i::StringShape(*str).IsExternalOneByte()) {
5311 const ExternalOneByteStringResource* resource =
5312 reinterpret_cast<const ExternalOneByteStringResource*>(
5313 i::Handle<i::ExternalOneByteString>::cast(str)->resource());
5314 expected = static_cast<const ExternalStringResourceBase*>(resource);
5315 expected_encoding = ONE_BYTE_ENCODING;
5316 actual_data_ptr = reinterpret_cast<const void*>(resource->data());
5317 actual_length = resource->length();
5318 } else if (i::StringShape(*str).IsExternalTwoByte()) {
5319 const ExternalStringResource* resource =
5320 reinterpret_cast<const ExternalStringResource*>(
5321 i::Handle<i::ExternalTwoByteString>::cast(str)->resource());
5322 expected = static_cast<const ExternalStringResourceBase*>(resource);
5323 expected_encoding = TWO_BYTE_ENCODING;
5324 actual_data_ptr = reinterpret_cast<const void*>(resource->data());
5325 actual_length = resource->length();
5311 } else { 5326 } else {
5312 expected = NULL; 5327 expected_encoding =
5313 }
5314 CHECK_EQ(expected, value);
5315 }
5316
5317 void v8::String::VerifyExternalStringResourceBase(
5318 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5319 i::Handle<i::String> str = Utils::OpenHandle(this);
5320 const v8::String::ExternalStringResourceBase* expected;
5321 Encoding expectedEncoding;
5322 if (i::StringShape(*str).IsExternalOneByte()) {
5323 const void* resource =
5324 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5325 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5326 expectedEncoding = ONE_BYTE_ENCODING;
5327 } else if (i::StringShape(*str).IsExternalTwoByte()) {
5328 const void* resource =
5329 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5330 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5331 expectedEncoding = TWO_BYTE_ENCODING;
5332 } else {
5333 expected = NULL;
5334 expectedEncoding =
5335 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING; 5328 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5336 } 5329 }
5337 CHECK_EQ(expected, value); 5330 CHECK_EQ(expected, value);
5338 CHECK_EQ(expectedEncoding, encoding); 5331 CHECK_EQ(expected_encoding, encoding);
5332 CHECK_EQ(i::Handle<i::ExternalString>::cast(str)->resource_data(),
5333 actual_data_ptr);
5334 CHECK_EQ(str->length(), static_cast<int>(actual_length));
5339 } 5335 }
5340 5336
5337
5341 const v8::String::ExternalOneByteStringResource* 5338 const v8::String::ExternalOneByteStringResource*
5342 v8::String::GetExternalOneByteStringResource() const { 5339 v8::String::GetExternalOneByteStringResource() const {
5343 i::Handle<i::String> str = Utils::OpenHandle(this); 5340 i::Handle<i::String> str = Utils::OpenHandle(this);
5341 const ExternalOneByteStringResource* result;
5344 if (i::StringShape(*str).IsExternalOneByte()) { 5342 if (i::StringShape(*str).IsExternalOneByte()) {
5345 const void* resource = 5343 const void* resource =
5346 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); 5344 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5347 return reinterpret_cast<const ExternalOneByteStringResource*>(resource); 5345 result = reinterpret_cast<const ExternalOneByteStringResource*>(resource);
5348 } else { 5346 } else {
5349 return NULL; 5347 result = nullptr;
5350 } 5348 }
5349 #ifdef V8_ENABLE_CHECKS
5350 VerifyExternalStringResourceBase(result, ONE_BYTE_ENCODING);
5351 #endif
5352 return result;
5351 } 5353 }
5352 5354
5353 5355
5354 Local<Value> Symbol::Name() const { 5356 Local<Value> Symbol::Name() const {
5355 i::Handle<i::Symbol> sym = Utils::OpenHandle(this); 5357 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5356 i::Handle<i::Object> name(sym->name(), sym->GetIsolate()); 5358 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
5357 return Utils::ToLocal(name); 5359 return Utils::ToLocal(name);
5358 } 5360 }
5359 5361
5360 5362
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
5917 // TODO(dcarney): throw a context free exception. 5919 // TODO(dcarney): throw a context free exception.
5918 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { 5920 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
5919 return MaybeLocal<String>(); 5921 return MaybeLocal<String>();
5920 } 5922 }
5921 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5923 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5922 ENTER_V8(i_isolate); 5924 ENTER_V8(i_isolate);
5923 LOG_API(i_isolate, "String::NewExternalTwoByte"); 5925 LOG_API(i_isolate, "String::NewExternalTwoByte");
5924 i::Handle<i::String> string = i_isolate->factory() 5926 i::Handle<i::String> string = i_isolate->factory()
5925 ->NewExternalStringFromTwoByte(resource) 5927 ->NewExternalStringFromTwoByte(resource)
5926 .ToHandleChecked(); 5928 .ToHandleChecked();
5929 #ifdef V8_ENABLE_CHECKS
5930 Utils::ToLocal(string)
5931 ->VerifyExternalStringResourceBase(resource, TWO_BYTE_ENCODING);
5932 #endif
5927 i_isolate->heap()->external_string_table()->AddString(*string); 5933 i_isolate->heap()->external_string_table()->AddString(*string);
5928 return Utils::ToLocal(string); 5934 return Utils::ToLocal(string);
5929 } 5935 }
5930 5936
5931 5937
5932 Local<String> v8::String::NewExternal( 5938 Local<String> v8::String::NewExternal(
5933 Isolate* isolate, v8::String::ExternalStringResource* resource) { 5939 Isolate* isolate, v8::String::ExternalStringResource* resource) {
5934 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String); 5940 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String);
5935 } 5941 }
5936 5942
5937 5943
5938 MaybeLocal<String> v8::String::NewExternalOneByte( 5944 MaybeLocal<String> v8::String::NewExternalOneByte(
5939 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { 5945 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5940 CHECK(resource && resource->data()); 5946 CHECK(resource && resource->data());
5941 // TODO(dcarney): throw a context free exception. 5947 // TODO(dcarney): throw a context free exception.
5942 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { 5948 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
5943 return MaybeLocal<String>(); 5949 return MaybeLocal<String>();
5944 } 5950 }
5945 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5951 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5946 ENTER_V8(i_isolate); 5952 ENTER_V8(i_isolate);
5947 LOG_API(i_isolate, "String::NewExternalOneByte"); 5953 LOG_API(i_isolate, "String::NewExternalOneByte");
5948 i::Handle<i::String> string = i_isolate->factory() 5954 i::Handle<i::String> string = i_isolate->factory()
5949 ->NewExternalStringFromOneByte(resource) 5955 ->NewExternalStringFromOneByte(resource)
5950 .ToHandleChecked(); 5956 .ToHandleChecked();
5951 i_isolate->heap()->external_string_table()->AddString(*string); 5957 i_isolate->heap()->external_string_table()->AddString(*string);
5958 #ifdef V8_ENABLE_CHECKS
5959 Utils::ToLocal(string)
5960 ->VerifyExternalStringResourceBase(resource, ONE_BYTE_ENCODING);
5961 #endif
5952 return Utils::ToLocal(string); 5962 return Utils::ToLocal(string);
5953 } 5963 }
5954 5964
5955 5965
5956 Local<String> v8::String::NewExternal( 5966 Local<String> v8::String::NewExternal(
5957 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { 5967 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5958 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String); 5968 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String);
5959 } 5969 }
5960 5970
5961 5971
(...skipping 10 matching lines...) Expand all
5972 if (isolate->heap()->IsInGCPostProcessing()) { 5982 if (isolate->heap()->IsInGCPostProcessing()) {
5973 return false; 5983 return false;
5974 } 5984 }
5975 CHECK(resource && resource->data()); 5985 CHECK(resource && resource->data());
5976 5986
5977 bool result = obj->MakeExternal(resource); 5987 bool result = obj->MakeExternal(resource);
5978 // Assert that if CanMakeExternal(), then externalizing actually succeeds. 5988 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5979 DCHECK(!CanMakeExternal() || result); 5989 DCHECK(!CanMakeExternal() || result);
5980 if (result) { 5990 if (result) {
5981 DCHECK(obj->IsExternalString()); 5991 DCHECK(obj->IsExternalString());
5992 #ifdef V8_ENABLE_CHECKS
5993 VerifyExternalStringResourceBase(resource, TWO_BYTE_ENCODING);
5994 #endif
5982 isolate->heap()->external_string_table()->AddString(*obj); 5995 isolate->heap()->external_string_table()->AddString(*obj);
5983 } 5996 }
5984 return result; 5997 return result;
5985 } 5998 }
5986 5999
5987 6000
5988 bool v8::String::MakeExternal( 6001 bool v8::String::MakeExternal(
5989 v8::String::ExternalOneByteStringResource* resource) { 6002 v8::String::ExternalOneByteStringResource* resource) {
5990 i::Handle<i::String> obj = Utils::OpenHandle(this); 6003 i::Handle<i::String> obj = Utils::OpenHandle(this);
5991 i::Isolate* isolate = obj->GetIsolate(); 6004 i::Isolate* isolate = obj->GetIsolate();
5992 if (i::StringShape(*obj).IsExternal()) { 6005 if (i::StringShape(*obj).IsExternal()) {
5993 return false; // Already an external string. 6006 return false; // Already an external string.
5994 } 6007 }
5995 ENTER_V8(isolate); 6008 ENTER_V8(isolate);
5996 if (isolate->string_tracker()->IsFreshUnusedString(obj)) { 6009 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5997 return false; 6010 return false;
5998 } 6011 }
5999 if (isolate->heap()->IsInGCPostProcessing()) { 6012 if (isolate->heap()->IsInGCPostProcessing()) {
6000 return false; 6013 return false;
6001 } 6014 }
6002 CHECK(resource && resource->data()); 6015 CHECK(resource && resource->data());
6003 6016
6004 bool result = obj->MakeExternal(resource); 6017 bool result = obj->MakeExternal(resource);
6005 // Assert that if CanMakeExternal(), then externalizing actually succeeds. 6018 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
6006 DCHECK(!CanMakeExternal() || result); 6019 DCHECK(!CanMakeExternal() || result);
6007 if (result) { 6020 if (result) {
6008 DCHECK(obj->IsExternalString()); 6021 DCHECK(obj->IsExternalString());
6022 #ifdef V8_ENABLE_CHECKS
6023 VerifyExternalStringResourceBase(resource, ONE_BYTE_ENCODING);
6024 #endif
6009 isolate->heap()->external_string_table()->AddString(*obj); 6025 isolate->heap()->external_string_table()->AddString(*obj);
6010 } 6026 }
6011 return result; 6027 return result;
6012 } 6028 }
6013 6029
6014 6030
6015 bool v8::String::CanMakeExternal() { 6031 bool v8::String::CanMakeExternal() {
6016 i::Handle<i::String> obj = Utils::OpenHandle(this); 6032 i::Handle<i::String> obj = Utils::OpenHandle(this);
6017 i::Isolate* isolate = obj->GetIsolate(); 6033 i::Isolate* isolate = obj->GetIsolate();
6018 6034
(...skipping 2371 matching lines...) Expand 10 before | Expand all | Expand 10 after
8390 Address callback_address = 8406 Address callback_address =
8391 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); 8407 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
8392 VMState<EXTERNAL> state(isolate); 8408 VMState<EXTERNAL> state(isolate);
8393 ExternalCallbackScope call_scope(isolate, callback_address); 8409 ExternalCallbackScope call_scope(isolate, callback_address);
8394 callback(info); 8410 callback(info);
8395 } 8411 }
8396 8412
8397 8413
8398 } // namespace internal 8414 } // namespace internal
8399 } // namespace v8 8415 } // namespace v8
OLDNEW
« no previous file with comments | « include/v8.h ('k') | src/heap/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698