Heavy cleanup of the external pointer API.

Added highly efficient Object::SetAlignedPointerInInternalField and
Object::GetAlignedPointerFromInternalField functions for 2-byte-aligned
pointers. Their non-aligned counterparts Object::GetPointerFromInternalField and
Object::SetPointerInInternalField are now deprecated utility functions.

External is now a true Value again, with New/Value/Cast using a JSObject with an
internal field containing a Foreign. External::Wrap, and External::Unwrap are now
deprecated utility functions.

Added Context::GetEmbedderData and Context::SetEmbedderData. Deprecated
Context::GetData and Context::SetData, these are now only wrappers to access
internal field 0.

Added highly efficient Context::SetAlignedPointerInEmbedderData and
Context::GetAlignedPointerFromEmbedderData functions for 2-byte-aligned
pointers.

Review URL: https://codereview.chromium.org/11190050

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12849 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 24bb0668
This diff is collapsed.
This diff is collapsed.
......@@ -201,8 +201,6 @@ class Utils {
v8::internal::Handle<v8::internal::JSObject> obj);
static inline Local<Array> ToLocal(
v8::internal::Handle<v8::internal::JSArray> obj);
static inline Local<External> ToLocal(
v8::internal::Handle<v8::internal::Foreign> obj);
static inline Local<Message> MessageToLocal(
v8::internal::Handle<v8::internal::Object> obj);
static inline Local<StackTrace> StackTraceToLocal(
......@@ -225,6 +223,8 @@ class Utils {
v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
static inline Local<TypeSwitch> ToLocal(
v8::internal::Handle<v8::internal::TypeSwitchInfo> obj);
static inline Local<External> ExternalToLocal(
v8::internal::Handle<v8::internal::JSObject> obj);
#define DECLARE_OPEN_HANDLE(From, To) \
static inline v8::internal::Handle<v8::internal::To> \
......@@ -268,7 +268,6 @@ MAKE_TO_LOCAL(ToLocal, String, String)
MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
MAKE_TO_LOCAL(ToLocal, JSObject, Object)
MAKE_TO_LOCAL(ToLocal, JSArray, Array)
MAKE_TO_LOCAL(ToLocal, Foreign, External)
MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
MAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature)
......@@ -280,6 +279,7 @@ MAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame)
MAKE_TO_LOCAL(NumberToLocal, Object, Number)
MAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
#undef MAKE_TO_LOCAL
......
......@@ -1240,8 +1240,9 @@ bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// Initialize the out of memory slot.
native_context()->set_out_of_memory(heap->false_value());
// Initialize the data slot.
native_context()->set_data(heap->undefined_value());
// Initialize the embedder data slot.
Handle<FixedArray> embedder_data = factory->NewFixedArray(2);
native_context()->set_embedder_data(*embedder_data);
{
// Initialize the random seed slot.
......
......@@ -432,7 +432,9 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
ASSERT(!isolate->native_context().is_null());
Handle<Script> script = info->script();
script->set_context_data((*isolate->native_context())->data());
// TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
FixedArray* array = isolate->native_context()->embedder_data();
script->set_context_data(array->get(0));
#ifdef ENABLE_DEBUGGER_SUPPORT
if (info->is_eval()) {
......
......@@ -152,7 +152,7 @@ enum BindingFlags {
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \
V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(CONTEXT_DATA_INDEX, Object, data) \
V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \
V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
error_message_for_code_gen_from_strings) \
......@@ -281,7 +281,7 @@ class Context: public FixedArray {
OPAQUE_REFERENCE_FUNCTION_INDEX,
CONTEXT_EXTENSION_FUNCTION_INDEX,
OUT_OF_MEMORY_INDEX,
CONTEXT_DATA_INDEX,
EMBEDDER_DATA_INDEX,
ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
......@@ -446,6 +446,9 @@ class Context: public FixedArray {
static bool IsBootstrappingOrValidParentContext(Object* object, Context* kid);
static bool IsBootstrappingOrGlobalObject(Object* object);
#endif
STATIC_CHECK(kHeaderSize == Internals::kContextHeaderSize);
STATIC_CHECK(EMBEDDER_DATA_INDEX == Internals::kContextEmbedderDataIndex);
};
} } // namespace v8::internal
......
......@@ -525,6 +525,12 @@ Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
}
Handle<FixedArray> Factory::CopySizeFixedArray(Handle<FixedArray> array,
int new_length) {
CALL_HEAP_FUNCTION(isolate(), array->CopySize(new_length), FixedArray);
}
Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
Handle<FixedDoubleArray> array) {
CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedDoubleArray);
......@@ -870,6 +876,13 @@ Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
}
Handle<JSObject> Factory::NewExternal(void* value) {
CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateExternal(value),
JSObject);
}
Handle<Code> Factory::NewCode(const CodeDesc& desc,
Code::Flags flags,
Handle<Object> self_ref,
......
......@@ -239,6 +239,9 @@ class Factory {
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
Handle<FixedArray> CopySizeFixedArray(Handle<FixedArray> array,
int new_length);
Handle<FixedDoubleArray> CopyFixedDoubleArray(
Handle<FixedDoubleArray> array);
......@@ -325,6 +328,8 @@ class Factory {
Handle<ScopeInfo> NewScopeInfo(int length);
Handle<JSObject> NewExternal(void* value);
Handle<Code> NewCode(const CodeDesc& desc,
Code::Flags flags,
Handle<Object> self_reference,
......
......@@ -2531,6 +2531,14 @@ bool Heap::CreateInitialMaps() {
}
set_message_object_map(Map::cast(obj));
Map* external_map;
{ MaybeObject* maybe_obj =
AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
if (!maybe_obj->To(&external_map)) return false;
}
external_map->set_is_extensible(false);
set_external_map(external_map);
ASSERT(!InNewSpace(empty_fixed_array()));
return true;
}
......@@ -5133,6 +5141,20 @@ MaybeObject* Heap::AllocateScopeInfo(int length) {
}
MaybeObject* Heap::AllocateExternal(void* value) {
Foreign* foreign;
{ MaybeObject* maybe_result = AllocateForeign(static_cast<Address>(value));
if (!maybe_result->To(&foreign)) return maybe_result;
}
JSObject* external;
{ MaybeObject* maybe_result = AllocateJSObjectFromMap(external_map());
if (!maybe_result->To(&external)) return maybe_result;
}
external->SetInternalField(0, foreign);
return external;
}
MaybeObject* Heap::AllocateStruct(InstanceType type) {
Map* map;
switch (type) {
......
......@@ -154,7 +154,8 @@ namespace internal {
V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \
V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \
V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \
V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset)
V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) \
V(Map, external_map, ExternalMap)
#define ROOT_LIST(V) \
STRONG_ROOT_LIST(V) \
......@@ -664,6 +665,9 @@ class Heap {
// Allocates a serialized scope info.
MUST_USE_RESULT MaybeObject* AllocateScopeInfo(int length);
// Allocates an External object for v8's external API.
MUST_USE_RESULT MaybeObject* AllocateExternal(void* value);
// Allocates an empty PolymorphicCodeCache.
MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
......
......@@ -134,6 +134,14 @@ bool Object::IsFixedArrayBase() {
}
// External objects are not extensible, so the map check is enough.
bool Object::IsExternal() {
return Object::IsHeapObject() &&
HeapObject::cast(this)->map() ==
HeapObject::cast(this)->GetHeap()->external_map();
}
bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
// There is a constraint on the object; check.
if (!this->IsJSObject()) return false;
......
......@@ -887,6 +887,7 @@ class Object : public MaybeObject {
#undef IS_TYPE_FUNCTION_DECL
inline bool IsFixedArrayBase();
inline bool IsExternal();
// Returns true if this object is an instance of the specified
// function template.
......@@ -2410,6 +2411,8 @@ class FixedArray: public FixedArrayBase {
Object* value);
private:
STATIC_CHECK(kHeaderSize == Internals::kFixedArrayHeaderSize);
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
};
......
......@@ -1988,7 +1988,7 @@ void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
"(context func. result caches)");
TagObject(context->normalized_map_cache(), "(context norm. map cache)");
TagObject(context->runtime_context(), "(runtime context)");
TagObject(context->data(), "(context data)");
TagObject(context->embedder_data(), "(context data)");
NATIVE_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
#undef EXTRACT_CONTEXT_FIELD
for (int i = Context::FIRST_WEAK_SLOT;
......
......@@ -25,6 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// We want to test our deprecated API entries, too.
#define V8_DISABLE_DEPRECATIONS 1
#include <limits.h>
#ifndef WIN32
......@@ -2056,6 +2059,99 @@ THREADED_TEST(InternalFieldsNativePointersAndExternal) {
}
static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj,
void* value) {
CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1));
obj->SetPointerInInternalField(0, value);
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(value, obj->GetPointerFromInternalField(0));
}
THREADED_TEST(InternalFieldsAlignedPointers) {
v8::HandleScope scope;
LocalContext env;
Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
instance_templ->SetInternalFieldCount(1);
Local<v8::Object> obj = templ->GetFunction()->NewInstance();
CHECK_EQ(1, obj->InternalFieldCount());
CheckAlignedPointerInInternalField(obj, NULL);
int* heap_allocated = new int[100];
CheckAlignedPointerInInternalField(obj, heap_allocated);
delete[] heap_allocated;
int stack_allocated[100];
CheckAlignedPointerInInternalField(obj, stack_allocated);
void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1));
CheckAlignedPointerInInternalField(obj, huge);
}
static void CheckAlignedPointerInEmbedderData(LocalContext* env,
int index,
void* value) {
CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1));
(*env)->SetAlignedPointerInEmbedderData(index, value);
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(value, (*env)->GetAlignedPointerFromEmbedderData(index));
}
static void* AlignedTestPointer(int i) {
return reinterpret_cast<void*>(i * 1234);
}
THREADED_TEST(EmbedderDataAlignedPointers) {
v8::HandleScope scope;
LocalContext env;
CheckAlignedPointerInEmbedderData(&env, 0, NULL);
int* heap_allocated = new int[100];
CheckAlignedPointerInEmbedderData(&env, 1, heap_allocated);
delete[] heap_allocated;
int stack_allocated[100];
CheckAlignedPointerInEmbedderData(&env, 2, stack_allocated);
void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1));
CheckAlignedPointerInEmbedderData(&env, 3, huge);
// Test growing of the embedder data's backing store.
for (int i = 0; i < 100; i++) {
env->SetAlignedPointerInEmbedderData(i, AlignedTestPointer(i));
}
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
for (int i = 0; i < 100; i++) {
CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i));
}
}
static void CheckEmbedderData(LocalContext* env,
int index,
v8::Handle<Value> data) {
(*env)->SetEmbedderData(index, data);
CHECK((*env)->GetEmbedderData(index)->StrictEquals(data));
}
THREADED_TEST(EmbedderData) {
v8::HandleScope scope;
LocalContext env;
CheckEmbedderData(&env, 3, v8::String::New("The quick brown fox jumps"));
CheckEmbedderData(&env, 2, v8::String::New("over the lazy dog."));
CheckEmbedderData(&env, 1, v8::Number::New(1.2345));
CheckEmbedderData(&env, 0, v8::Boolean::New(true));
}
THREADED_TEST(IdentityHash) {
v8::HandleScope scope;
LocalContext env;
......
......@@ -27,6 +27,9 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
// TODO(svenpanne): Do not use Context::GetData and Context::SetData.
#define V8_DISABLE_DEPRECATIONS 1
#include <stdlib.h>
#include "v8.h"
......
......@@ -190,7 +190,8 @@ v8::Handle<Integer> DeclarationContext::HandleQuery(Local<String> key,
DeclarationContext* DeclarationContext::GetInstance(const AccessorInfo& info) {
return static_cast<DeclarationContext*>(External::Unwrap(info.Data()));
void* value = External::Cast(*info.Data())->Value();
return static_cast<DeclarationContext*>(value);
}
......
......@@ -863,80 +863,82 @@ INSTANCE_TYPES = {
# }
# printf("}\n");
KNOWN_MAPS = {
0x08081: (134, "ByteArrayMap"),
0x080a1: (128, "MetaMap"),
0x080c1: (130, "OddballMap"),
0x080e1: (163, "FixedArrayMap"),
0x08101: (68, "AsciiSymbolMap"),
0x08121: (132, "HeapNumberMap"),
0x08141: (135, "FreeSpaceMap"),
0x08161: (146, "OnePointerFillerMap"),
0x08181: (146, "TwoPointerFillerMap"),
0x081a1: (131, "GlobalPropertyCellMap"),
0x081c1: (164, "SharedFunctionInfoMap"),
0x081e1: (4, "AsciiStringMap"),
0x08201: (163, "GlobalContextMap"),
0x08221: (129, "CodeMap"),
0x08241: (163, "ScopeInfoMap"),
0x08261: (163, "FixedCOWArrayMap"),
0x08281: (145, "FixedDoubleArrayMap"),
0x082a1: (163, "HashTableMap"),
0x082c1: (0, "StringMap"),
0x082e1: (64, "SymbolMap"),
0x08301: (1, "ConsStringMap"),
0x08321: (5, "ConsAsciiStringMap"),
0x08341: (3, "SlicedStringMap"),
0x08361: (7, "SlicedAsciiStringMap"),
0x08381: (65, "ConsSymbolMap"),
0x083a1: (69, "ConsAsciiSymbolMap"),
0x083c1: (66, "ExternalSymbolMap"),
0x083e1: (74, "ExternalSymbolWithAsciiDataMap"),
0x08401: (70, "ExternalAsciiSymbolMap"),
0x08421: (2, "ExternalStringMap"),
0x08441: (10, "ExternalStringWithAsciiDataMap"),
0x08461: (6, "ExternalAsciiStringMap"),
0x08481: (82, "ShortExternalSymbolMap"),
0x084a1: (90, "ShortExternalSymbolWithAsciiDataMap"),
0x084c1: (86, "ShortExternalAsciiSymbolMap"),
0x084e1: (18, "ShortExternalStringMap"),
0x08501: (26, "ShortExternalStringWithAsciiDataMap"),
0x08521: (22, "ShortExternalAsciiStringMap"),
0x08541: (0, "UndetectableStringMap"),
0x08561: (4, "UndetectableAsciiStringMap"),
0x08581: (144, "ExternalPixelArrayMap"),
0x085a1: (136, "ExternalByteArrayMap"),
0x085c1: (137, "ExternalUnsignedByteArrayMap"),
0x085e1: (138, "ExternalShortArrayMap"),
0x08601: (139, "ExternalUnsignedShortArrayMap"),
0x08621: (140, "ExternalIntArrayMap"),
0x08641: (141, "ExternalUnsignedIntArrayMap"),
0x08661: (142, "ExternalFloatArrayMap"),
0x08681: (143, "ExternalDoubleArrayMap"),
0x086a1: (163, "NonStrictArgumentsElementsMap"),
0x086c1: (163, "FunctionContextMap"),
0x086e1: (163, "CatchContextMap"),
0x08701: (163, "WithContextMap"),
0x08721: (163, "BlockContextMap"),
0x08741: (163, "ModuleContextMap"),
0x08761: (165, "JSMessageObjectMap"),
0x08781: (133, "ForeignMap"),
0x087a1: (170, "NeanderMap"),
0x087c1: (158, "PolymorphicCodeCacheMap"),
0x087e1: (156, "ScriptMap"),
0x08801: (147, "AccessorInfoMap"),
0x08821: (148, "AccessorPairMap"),
0x08841: (149, "AccessCheckInfoMap"),
0x08861: (150, "InterceptorInfoMap"),
0x08881: (151, "CallHandlerInfoMap"),
0x088a1: (152, "FunctionTemplateInfoMap"),
0x088c1: (153, "ObjectTemplateInfoMap"),
0x088e1: (154, "SignatureInfoMap"),
0x08901: (155, "TypeSwitchInfoMap"),
0x08921: (157, "CodeCacheMap"),
0x08941: (159, "TypeFeedbackInfoMap"),
0x08961: (160, "AliasedArgumentsEntryMap"),
0x08981: (161, "DebugInfoMap"),
0x089a1: (162, "BreakPointInfoMap"),
0x08081: (128, "MetaMap"),
0x080a5: (163, "FixedArrayMap"),
0x080c9: (130, "OddballMap"),
0x080ed: (163, "FixedCOWArrayMap"),
0x08111: (163, "ScopeInfoMap"),
0x08135: (132, "HeapNumberMap"),
0x08159: (133, "ForeignMap"),
0x0817d: (64, "SymbolMap"),
0x081a1: (68, "AsciiSymbolMap"),
0x081c5: (65, "ConsSymbolMap"),
0x081e9: (69, "ConsAsciiSymbolMap"),
0x0820d: (66, "ExternalSymbolMap"),
0x08231: (74, "ExternalSymbolWithAsciiDataMap"),
0x08255: (70, "ExternalAsciiSymbolMap"),
0x08279: (82, "ShortExternalSymbolMap"),
0x0829d: (90, "ShortExternalSymbolWithAsciiDataMap"),
0x082c1: (86, "ShortExternalAsciiSymbolMap"),
0x082e5: (0, "StringMap"),
0x08309: (4, "AsciiStringMap"),
0x0832d: (1, "ConsStringMap"),
0x08351: (5, "ConsAsciiStringMap"),
0x08375: (3, "SlicedStringMap"),
0x08399: (7, "SlicedAsciiStringMap"),
0x083bd: (2, "ExternalStringMap"),
0x083e1: (10, "ExternalStringWithAsciiDataMap"),
0x08405: (6, "ExternalAsciiStringMap"),
0x08429: (18, "ShortExternalStringMap"),
0x0844d: (26, "ShortExternalStringWithAsciiDataMap"),
0x08471: (22, "ShortExternalAsciiStringMap"),
0x08495: (0, "UndetectableStringMap"),
0x084b9: (4, "UndetectableAsciiStringMap"),
0x084dd: (145, "FixedDoubleArrayMap"),
0x08501: (134, "ByteArrayMap"),
0x08525: (135, "FreeSpaceMap"),
0x08549: (144, "ExternalPixelArrayMap"),
0x0856d: (136, "ExternalByteArrayMap"),
0x08591: (137, "ExternalUnsignedByteArrayMap"),
0x085b5: (138, "ExternalShortArrayMap"),
0x085d9: (139, "ExternalUnsignedShortArrayMap"),
0x085fd: (140, "ExternalIntArrayMap"),
0x08621: (141, "ExternalUnsignedIntArrayMap"),
0x08645: (142, "ExternalFloatArrayMap"),
0x08669: (163, "NonStrictArgumentsElementsMap"),
0x0868d: (143, "ExternalDoubleArrayMap"),
0x086b1: (129, "CodeMap"),
0x086d5: (131, "GlobalPropertyCellMap"),
0x086f9: (146, "OnePointerFillerMap"),
0x0871d: (146, "TwoPointerFillerMap"),
0x08741: (147, "AccessorInfoMap"),
0x08765: (148, "AccessorPairMap"),
0x08789: (149, "AccessCheckInfoMap"),
0x087ad: (150, "InterceptorInfoMap"),
0x087d1: (151, "CallHandlerInfoMap"),
0x087f5: (152, "FunctionTemplateInfoMap"),
0x08819: (153, "ObjectTemplateInfoMap"),
0x0883d: (154, "SignatureInfoMap"),
0x08861: (155, "TypeSwitchInfoMap"),
0x08885: (156, "ScriptMap"),
0x088a9: (157, "CodeCacheMap"),
0x088cd: (158, "PolymorphicCodeCacheMap"),
0x088f1: (159, "TypeFeedbackInfoMap"),
0x08915: (160, "AliasedArgumentsEntryMap"),
0x08939: (161, "DebugInfoMap"),
0x0895d: (162, "BreakPointInfoMap"),
0x08981: (163, "HashTableMap"),
0x089a5: (163, "FunctionContextMap"),
0x089c9: (163, "CatchContextMap"),
0x089ed: (163, "WithContextMap"),
0x08a11: (163, "BlockContextMap"),
0x08a35: (163, "ModuleContextMap"),
0x08a59: (163, "GlobalContextMap"),
0x08a7d: (163, "NativeContextMap"),
0x08aa1: (164, "SharedFunctionInfoMap"),
0x08ac5: (165, "JSMessageObjectMap"),
0x08ae9: (170, "ExternalMap"),
0x08b0d: (170, "NeanderMap"),
}
......
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