Commit 06360928 authored by danno@chromium.org's avatar danno@chromium.org

Add a faster API for creating v8::Integer objects

In WebKit, we have a small integer cache because calling v8::Integer::New is
slow. This patch adds a faster API for creating integers that requires the
caller to supply the v8::Isolate, saving us the work of looking up the isolate
in thread-local storage.

BUG=

Review URL: https://codereview.chromium.org/11212004
Patch from Adam Barth <abarth@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12773 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a0c9856b
......@@ -1389,6 +1389,8 @@ class Integer : public Number {
public:
V8EXPORT static Local<Integer> New(int32_t value);
V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value);
V8EXPORT static Local<Integer> New(int32_t value, Isolate*);
V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value, Isolate*);
V8EXPORT int64_t Value() const;
static inline Integer* Cast(v8::Value* obj);
private:
......
......@@ -5228,24 +5228,39 @@ Local<Number> v8::Number::New(double value) {
Local<Integer> v8::Integer::New(int32_t value) {
i::Isolate* isolate = i::Isolate::UncheckedCurrent();
EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
return v8::Integer::New(value, reinterpret_cast<Isolate*>(isolate));
}
Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Integer::NewFromUnsigned()");
return Integer::NewFromUnsigned(value, reinterpret_cast<Isolate*>(isolate));
}
Local<Integer> v8::Integer::New(int32_t value, Isolate* isolate) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
ASSERT(internal_isolate->IsInitialized());
if (i::Smi::IsValid(value)) {
return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
isolate));
internal_isolate));
}
ENTER_V8(isolate);
i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
ENTER_V8(internal_isolate);
i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
Local<Integer> v8::Integer::NewFromUnsigned(uint32_t value, Isolate* isolate) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
ASSERT(internal_isolate->IsInitialized());
bool fits_into_int32_t = (value & (1 << 31)) == 0;
if (fits_into_int32_t) {
return Integer::New(static_cast<int32_t>(value));
return Integer::New(static_cast<int32_t>(value), isolate);
}
i::Isolate* isolate = i::Isolate::Current();
ENTER_V8(isolate);
i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
ENTER_V8(internal_isolate);
i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
return Utils::IntegerToLocal(result);
}
......
......@@ -969,22 +969,33 @@ THREADED_TEST(FindInstanceInPrototypeChain) {
THREADED_TEST(TinyInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
int32_t value = 239;
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::New(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigSmiInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
int32_t value = i::Smi::kMaxValue;
// We cannot add one to a Smi::kMaxValue without wrapping.
if (i::kSmiValueSize < 32) {
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::New(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
......@@ -992,6 +1003,8 @@ THREADED_TEST(BigSmiInteger) {
THREADED_TEST(BigInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
// We cannot add one to a Smi::kMaxValue without wrapping.
if (i::kSmiValueSize < 32) {
// The casts allow this to compile, even if Smi::kMaxValue is 2^31-1.
......@@ -1000,8 +1013,12 @@ THREADED_TEST(BigInteger) {
static_cast<int32_t>(static_cast<uint32_t>(i::Smi::kMaxValue) + 1);
CHECK(value > i::Smi::kMaxValue);
CHECK(!i::Smi::IsValid(value));
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::New(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
......@@ -1009,42 +1026,66 @@ THREADED_TEST(BigInteger) {
THREADED_TEST(TinyUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
uint32_t value = 239;
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::NewFromUnsigned(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigUnsignedSmiInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue);
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::NewFromUnsigned(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue) + 1;
CHECK(value > static_cast<uint32_t>(i::Smi::kMaxValue));
CHECK(!i::Smi::IsValid(value));
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::NewFromUnsigned(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(OutOfSignedRangeUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
uint32_t INT32_MAX_AS_UINT = (1U << 31) - 1;
uint32_t value = INT32_MAX_AS_UINT + 1;
CHECK(value > INT32_MAX_AS_UINT); // No overflow.
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
value_obj = v8::Integer::NewFromUnsigned(value, isolate);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment