Reviewers: dano_chromium.org,
Message:
I wasn't sure whether we want to supply the isolate as the first parameter
or
the last parameter. I didn't find any other examples in the API of functions
that took an isolate and another parameter.
Description:
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=
Please review this at https://codereview.chromium.org/11212004/
SVN Base: git://github.com/v8/v8.git@master
Affected files:
include/v8.h
M src/api.cc
M test/cctest/test-api.cc
Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index
ff44fdf28730b73b329e91e032ca1c9cdb5da75e..01beb884b04f6b735182513a64f0cf59d07df92d
100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1384,6 +1384,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:
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
dcadf52a6a64dcb2a6022fbbe80a10fff2d3ad33..d6336a131a40f3d70fa6738b21b72e18c1288fbf
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -5191,24 +5191,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);
}
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
a8f340db2e4e89627fa1718cea71b7bf5ca73e88..7771422631b99872290d06be12f16fc19d5d8339
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -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());
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev