- Do not allocate proxy objects if the pointer can be wrapped in a Smi representation.
Review URL: http://codereview.chromium.org/42466 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1568 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
80ce1b2500
commit
1db91bee34
@ -1151,6 +1151,10 @@ class V8EXPORT External : public Value {
|
||||
static External* Cast(Value* obj);
|
||||
void* Value() const;
|
||||
private:
|
||||
enum {
|
||||
kAlignedPointerMask = 3,
|
||||
kAlignedPointerShift = 2
|
||||
};
|
||||
External();
|
||||
};
|
||||
|
||||
|
17
src/api.cc
17
src/api.cc
@ -1447,7 +1447,7 @@ Local<Integer> Value::ToInteger() const {
|
||||
External* External::Cast(v8::Value* that) {
|
||||
if (IsDeadCheck("v8::External::Cast()")) return 0;
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(that);
|
||||
ApiCheck(obj->IsProxy(),
|
||||
ApiCheck(obj->IsProxy() || obj->IsSmi(),
|
||||
"v8::External::Cast()",
|
||||
"Could not convert to external");
|
||||
return static_cast<External*>(that);
|
||||
@ -2229,6 +2229,11 @@ int32_t Int32::Value() const {
|
||||
void* External::Value() const {
|
||||
if (IsDeadCheck("v8::External::Value()")) return 0;
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
if (obj->IsSmi()) {
|
||||
// The external value was an aligned pointer.
|
||||
return reinterpret_cast<void*>(
|
||||
i::Smi::cast(*obj)->value() << kAlignedPointerShift);
|
||||
}
|
||||
return reinterpret_cast<void*>(i::Proxy::cast(*obj)->proxy());
|
||||
}
|
||||
|
||||
@ -2467,8 +2472,14 @@ Local<External> v8::External::New(void* data) {
|
||||
STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
|
||||
LOG_API("External::New");
|
||||
EnsureInitialized("v8::External::New()");
|
||||
i::Handle<i::Proxy> obj = i::Factory::NewProxy(static_cast<i::Address>(data));
|
||||
return Utils::ToLocal(obj);
|
||||
if ((reinterpret_cast<intptr_t>(data) & kAlignedPointerMask) == 0) {
|
||||
uintptr_t data_ptr = reinterpret_cast<uintptr_t>(data);
|
||||
int data_value = static_cast<int>(data_ptr >> kAlignedPointerShift);
|
||||
STATIC_ASSERT(sizeof(data_ptr) == sizeof(data_value));
|
||||
i::Handle<i::Smi> obj(i::Smi::FromInt(data_value));
|
||||
return Utils::ToLocal(obj);
|
||||
}
|
||||
return Utils::ToLocal(i::Factory::NewProxy(static_cast<i::Address>(data)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,6 +181,8 @@ class Utils {
|
||||
v8::internal::Handle<v8::internal::JSArray> obj);
|
||||
static inline Local<External> ToLocal(
|
||||
v8::internal::Handle<v8::internal::Proxy> obj);
|
||||
static inline Local<External> ToLocal(
|
||||
v8::internal::Handle<v8::internal::Smi> obj);
|
||||
static inline Local<Message> MessageToLocal(
|
||||
v8::internal::Handle<v8::internal::Object> obj);
|
||||
static inline Local<Number> NumberToLocal(
|
||||
@ -256,6 +258,7 @@ MAKE_TO_LOCAL(ToLocal, String, String)
|
||||
MAKE_TO_LOCAL(ToLocal, JSObject, Object)
|
||||
MAKE_TO_LOCAL(ToLocal, JSArray, Array)
|
||||
MAKE_TO_LOCAL(ToLocal, Proxy, External)
|
||||
MAKE_TO_LOCAL(ToLocal, Smi, External)
|
||||
MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
|
||||
MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
|
||||
MAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature)
|
||||
|
@ -1339,6 +1339,22 @@ THREADED_TEST(External) {
|
||||
CHECK_EQ(x, 3);
|
||||
*ptr = 10;
|
||||
CHECK_EQ(x, 10);
|
||||
|
||||
// Make sure unaligned pointers are wrapped properly.
|
||||
char* data = "0123456789";
|
||||
Local<v8::External> zero = v8::External::New(&data[0]);
|
||||
Local<v8::External> one = v8::External::New(&data[1]);
|
||||
Local<v8::External> two = v8::External::New(&data[2]);
|
||||
Local<v8::External> three = v8::External::New(&data[3]);
|
||||
|
||||
char* char_ptr = reinterpret_cast<char*>(zero->Value());
|
||||
CHECK_EQ('0', *char_ptr);
|
||||
char_ptr = reinterpret_cast<char*>(one->Value());
|
||||
CHECK_EQ('1', *char_ptr);
|
||||
char_ptr = reinterpret_cast<char*>(two->Value());
|
||||
CHECK_EQ('2', *char_ptr);
|
||||
char_ptr = reinterpret_cast<char*>(three->Value());
|
||||
CHECK_EQ('3', *char_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user