Revision: 11417
Author:   [email protected]
Date:     Mon Apr 23 08:09:59 2012
Log:      Make static API getters inlineable again.

This relands r11376 with minor fixes for Windows where offsets are
slightly different from Linux for unaligned fields.

[email protected]
TEST=cctest/test-api/StaticGetters

Review URL: https://chromiumcodereview.appspot.com/10176004
http://code.google.com/p/v8/source/detail?r=11417

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Wed Apr 18 10:49:53 2012
+++ /branches/bleeding_edge/include/v8.h        Mon Apr 23 08:09:59 2012
@@ -2561,6 +2561,11 @@
 Handle<Boolean> V8EXPORT True();
 Handle<Boolean> V8EXPORT False();

+inline Handle<Primitive> Undefined(Isolate* isolate);
+inline Handle<Primitive> Null(Isolate* isolate);
+inline Handle<Boolean> True(Isolate* isolate);
+inline Handle<Boolean> False(Isolate* isolate);
+

 /**
* A set of constraints that specifies the limits of the runtime's memory use.
@@ -3872,18 +3877,6 @@
     PlatformSmiTagging::kEncodablePointerMask;
 const int kPointerToSmiShift = PlatformSmiTagging::kPointerToSmiShift;

-template <size_t ptr_size> struct InternalConstants;
-
-// Internal constants for 32-bit systems.
-template <> struct InternalConstants<4> {
-  static const int kStringResourceOffset = 3 * kApiPointerSize;
-};
-
-// Internal constants for 64-bit systems.
-template <> struct InternalConstants<8> {
-  static const int kStringResourceOffset = 3 * kApiPointerSize;
-};
-
 /**
  * This class exports constants and functionality from within v8 that
  * is necessary to implement inline functions in the v8 api.  Don't
@@ -3895,8 +3888,7 @@
   // the implementation of v8.
   static const int kHeapObjectMapOffset = 0;
static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize;
-  static const int kStringResourceOffset =
-      InternalConstants<kApiPointerSize>::kStringResourceOffset;
+  static const int kStringResourceOffset = 3 * kApiPointerSize;

   static const int kOddballKindOffset = 3 * kApiPointerSize;
   static const int kForeignAddressOffset = kApiPointerSize;
@@ -3904,6 +3896,14 @@
   static const int kFullStringRepresentationMask = 0x07;
   static const int kExternalTwoByteRepresentationTag = 0x02;

+  static const int kIsolateStateOffset = 0;
+  static const int kIsolateEmbedderDataOffset = 1 * kApiPointerSize;
+  static const int kIsolateRootsOffset = 3 * kApiPointerSize;
+  static const int kUndefinedValueRootIndex = 5;
+  static const int kNullValueRootIndex = 7;
+  static const int kTrueValueRootIndex = 8;
+  static const int kFalseValueRootIndex = 9;
+
   static const int kJSObjectType = 0xaa;
   static const int kFirstNonstringType = 0x80;
   static const int kOddballType = 0x82;
@@ -3955,6 +3955,16 @@
     int representation = (instance_type & kFullStringRepresentationMask);
     return representation == kExternalTwoByteRepresentationTag;
   }
+
+  static inline bool IsInitialized(v8::Isolate* isolate) {
+ uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateStateOffset;
+    return *reinterpret_cast<int*>(addr) == 1;
+  }
+
+ static inline internal::Object** GetRoot(v8::Isolate* isolate, int index) { + uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateRootsOffset; + return reinterpret_cast<internal::Object**>(addr + index * kApiPointerSize);
+  }

   template <typename T>
   static inline T ReadField(Object* ptr, int offset) {
@@ -4376,6 +4386,42 @@
 Local<Object> AccessorInfo::Holder() const {
   return Local<Object>(reinterpret_cast<Object*>(&args_[-1]));
 }
+
+
+Handle<Primitive> Undefined(Isolate* isolate) {
+  typedef internal::Object* S;
+  typedef internal::Internals I;
+  if (!I::IsInitialized(isolate)) return Undefined();
+  S* slot = I::GetRoot(isolate, I::kUndefinedValueRootIndex);
+  return Handle<Primitive>(reinterpret_cast<Primitive*>(slot));
+}
+
+
+Handle<Primitive> Null(Isolate* isolate) {
+  typedef internal::Object* S;
+  typedef internal::Internals I;
+  if (!I::IsInitialized(isolate)) return Null();
+  S* slot = I::GetRoot(isolate, I::kNullValueRootIndex);
+  return Handle<Primitive>(reinterpret_cast<Primitive*>(slot));
+}
+
+
+Handle<Boolean> True(Isolate* isolate) {
+  typedef internal::Object* S;
+  typedef internal::Internals I;
+  if (!I::IsInitialized(isolate)) return True();
+  S* slot = I::GetRoot(isolate, I::kTrueValueRootIndex);
+  return Handle<Boolean>(reinterpret_cast<Boolean*>(slot));
+}
+
+
+Handle<Boolean> False(Isolate* isolate) {
+  typedef internal::Object* S;
+  typedef internal::Internals I;
+  if (!I::IsInitialized(isolate)) return False();
+  S* slot = I::GetRoot(isolate, I::kFalseValueRootIndex);
+  return Handle<Boolean>(reinterpret_cast<Boolean*>(slot));
+}


 /**
=======================================
--- /branches/bleeding_edge/src/heap.h  Mon Apr 23 06:59:43 2012
+++ /branches/bleeding_edge/src/heap.h  Mon Apr 23 08:09:59 2012
@@ -1419,6 +1419,11 @@
     kRootListLength
   };

+ STATIC_CHECK(kUndefinedValueRootIndex == Internals::kUndefinedValueRootIndex);
+  STATIC_CHECK(kNullValueRootIndex == Internals::kNullValueRootIndex);
+  STATIC_CHECK(kTrueValueRootIndex == Internals::kTrueValueRootIndex);
+  STATIC_CHECK(kFalseValueRootIndex == Internals::kFalseValueRootIndex);
+
   MUST_USE_RESULT MaybeObject* NumberToString(
       Object* number, bool check_number_string_cache = true);
   MUST_USE_RESULT MaybeObject* Uint32ToString(
@@ -1613,6 +1618,8 @@
// more expedient to get at the isolate directly from within Heap methods.
   Isolate* isolate_;

+  Object* roots_[kRootListLength];
+
   intptr_t code_range_size_;
   int reserved_semispace_size_;
   int max_semispace_size_;
@@ -1728,8 +1735,6 @@
   // last GC.
   int old_gen_exhausted_;

-  Object* roots_[kRootListLength];
-
   Object* global_contexts_list_;

   StoreBufferRebuilder store_buffer_rebuilder_;
=======================================
--- /branches/bleeding_edge/src/isolate.cc      Fri Apr 20 07:12:49 2012
+++ /branches/bleeding_edge/src/isolate.cc      Mon Apr 23 08:09:59 2012
@@ -1430,6 +1430,7 @@

 Isolate::Isolate()
     : state_(UNINITIALIZED),
+      embedder_data_(NULL),
       entry_stack_(NULL),
       stack_trace_nesting_level_(0),
       incomplete_message_(NULL),
@@ -1472,7 +1473,6 @@
       string_tracker_(NULL),
       regexp_stack_(NULL),
       date_cache_(NULL),
-      embedder_data_(NULL),
       context_exit_happened_(false) {
   TRACE_ISOLATE(constructor);

@@ -1856,6 +1856,13 @@
     LOG(this, LogCodeObjects());
     LOG(this, LogCompiledFunctions());
   }
+
+  CHECK_EQ(OFFSET_OF(Isolate, state_),
+           static_cast<intptr_t>(Internals::kIsolateStateOffset));
+  CHECK_EQ(OFFSET_OF(Isolate, embedder_data_),
+           static_cast<intptr_t>(Internals::kIsolateEmbedderDataOffset));
+  CHECK_EQ(OFFSET_OF(Isolate, heap_.roots_),
+           static_cast<intptr_t>(Internals::kIsolateRootsOffset));

   state_ = INITIALIZED;
   time_millis_at_init_ = OS::TimeCurrentMillis();
=======================================
--- /branches/bleeding_edge/src/isolate.h       Wed Apr 18 10:49:53 2012
+++ /branches/bleeding_edge/src/isolate.h       Mon Apr 23 08:09:59 2012
@@ -422,7 +422,7 @@
   enum AddressId {
 #define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
     FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
-#undef C
+#undef DECLARE_ENUM
     kIsolateAddressCount
   };

@@ -1038,6 +1038,18 @@
   friend struct GlobalState;
   friend struct InitializeGlobalState;

+  enum State {
+    UNINITIALIZED,    // Some components may not have been allocated.
+    INITIALIZED       // All components are fully initialized.
+  };
+
+ // These fields are accessed through the API, offsets must be kept in sync
+  // with v8::internal::Internals (in include/v8.h) constants. This is also
+  // verified in Isolate::Init() using runtime checks.
+  State state_;  // Will be padded to kApiPointerSize.
+  void* embedder_data_;
+  Heap heap_;
+
   // The per-process lock should be acquired before the ThreadDataTable is
   // modified.
   class ThreadDataTable {
@@ -1095,14 +1107,6 @@
   static void SetIsolateThreadLocals(Isolate* isolate,
                                      PerIsolateThreadData* data);

-  enum State {
-    UNINITIALIZED,    // Some components may not have been allocated.
-    INITIALIZED       // All components are fully initialized.
-  };
-
-  State state_;
-  EntryStackItem* entry_stack_;
-
   // Allocate and insert PerIsolateThreadData into the ThreadDataTable
   // (regardless of whether such data already exists).
   PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id);
@@ -1146,13 +1150,13 @@
   // the Error object.
   bool IsErrorObject(Handle<Object> obj);

+  EntryStackItem* entry_stack_;
   int stack_trace_nesting_level_;
   StringStream* incomplete_message_;
   // The preallocated memory thread singleton.
   PreallocatedMemoryThread* preallocated_memory_thread_;
   Address isolate_addresses_[kIsolateAddressCount + 1];  // NOLINT
   NoAllocationStringAllocator* preallocated_message_space_;
-
   Bootstrapper* bootstrapper_;
   RuntimeProfiler* runtime_profiler_;
   CompilationCache* compilation_cache_;
@@ -1161,7 +1165,6 @@
   Mutex* break_access_;
   Atomic32 debugger_initialized_;
   Mutex* debugger_access_;
-  Heap heap_;
   Logger* logger_;
   StackGuard stack_guard_;
   StatsTable* stats_table_;
@@ -1202,11 +1205,8 @@
   unibrow::Mapping<unibrow::Ecma262Canonicalize>
       regexp_macro_assembler_canonicalize_;
   RegExpStack* regexp_stack_;
-
   DateCache* date_cache_;
-
unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
-  void* embedder_data_;

   // The garbage collector should be a little more aggressive when it knows
   // that a context was recently exited.
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Fri Apr 20 07:12:49 2012
+++ /branches/bleeding_edge/src/serialize.cc    Mon Apr 23 08:09:59 2012
@@ -244,7 +244,7 @@
     "Isolate::" #hacker_name "_address",
     FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL)
     NULL
-#undef C
+#undef BUILD_NAME_LITERAL
   };

   for (uint16_t i = 0; i < Isolate::kIsolateAddressCount; ++i) {
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Fri Apr 20 06:35:09 2012
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Mon Apr 23 08:09:59 2012
@@ -16448,3 +16448,59 @@
 TEST(PrimaryStubCache) {
   StubCacheHelper(false);
 }
+
+
+TEST(StaticGetters) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  i::Handle<i::Object> undefined_value = FACTORY->undefined_value();
+  CHECK(*v8::Utils::OpenHandle(*v8::Undefined()) == *undefined_value);
+ CHECK(*v8::Utils::OpenHandle(*v8::Undefined(isolate)) == *undefined_value);
+  i::Handle<i::Object> null_value = FACTORY->null_value();
+  CHECK(*v8::Utils::OpenHandle(*v8::Null()) == *null_value);
+  CHECK(*v8::Utils::OpenHandle(*v8::Null(isolate)) == *null_value);
+  i::Handle<i::Object> true_value = FACTORY->true_value();
+  CHECK(*v8::Utils::OpenHandle(*v8::True()) == *true_value);
+  CHECK(*v8::Utils::OpenHandle(*v8::True(isolate)) == *true_value);
+  i::Handle<i::Object> false_value = FACTORY->false_value();
+  CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value);
+  CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value);
+}
+
+
+static int fatal_error_callback_counter = 0;
+static void CountingErrorCallback(const char* location, const char* message) {
+  printf("CountingErrorCallback(\"%s\", \"%s\")\n", location, message);
+  fatal_error_callback_counter++;
+}
+
+
+TEST(StaticGettersAfterDeath) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  CHECK(i::Internals::IsInitialized(isolate));
+  CHECK_EQ(0, fatal_error_callback_counter);
+  v8::V8::SetFatalErrorHandler(CountingErrorCallback);
+  v8::Utils::ReportApiFailure("StaticGettersAfterDeath()", "Kill V8");
+  i::Isolate::Current()->TearDown();
+  CHECK(!i::Internals::IsInitialized(isolate));
+  CHECK_EQ(1, fatal_error_callback_counter);
+  CHECK(v8::Undefined().IsEmpty());
+  CHECK_EQ(2, fatal_error_callback_counter);
+  CHECK(v8::Undefined(isolate).IsEmpty());
+  CHECK_EQ(3, fatal_error_callback_counter);
+  CHECK(v8::Null().IsEmpty());
+  CHECK_EQ(4, fatal_error_callback_counter);
+  CHECK(v8::Null(isolate).IsEmpty());
+  CHECK_EQ(5, fatal_error_callback_counter);
+  CHECK(v8::True().IsEmpty());
+  CHECK_EQ(6, fatal_error_callback_counter);
+  CHECK(v8::True(isolate).IsEmpty());
+  CHECK_EQ(7, fatal_error_callback_counter);
+  CHECK(v8::False().IsEmpty());
+  CHECK_EQ(8, fatal_error_callback_counter);
+  CHECK(v8::False(isolate).IsEmpty());
+  CHECK_EQ(9, fatal_error_callback_counter);
+}

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to