Recommit reverted change, now with fixes to make it work with gcc-4.2.
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 3 Oct 2008 15:53:44 +0000 (15:53 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 3 Oct 2008 15:53:44 +0000 (15:53 +0000)
Allow gcc to use strict (type-based) aliasing when optimizing.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@431 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

SConstruct
src/api.h
src/assembler.cc
src/bootstrapper.cc
src/debug.cc
src/debug.h
src/globals.h
src/heap.cc
src/top.cc

index 265c877..96ce466 100644 (file)
@@ -43,8 +43,7 @@ LIBRARY_FLAGS = {
   'gcc': {
     'all': {
       'DIALECTFLAGS': ['-ansi'],
-      'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS',
-          '-fno-strict-aliasing'],
+      'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
       'CXXFLAGS':     ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
       'LIBS':         ['pthread']
     },
@@ -53,7 +52,7 @@ LIBRARY_FLAGS = {
       'CPPDEFINES':   ['ENABLE_DISASSEMBLER', 'DEBUG']
     },
     'mode:release': {
-      'CCFLAGS':      ['-O9']
+      'CCFLAGS':      ['-O3']
     },
     'wordsize:64': {
       'CCFLAGS':      ['-m32'],
index 18dea43..99cda18 100644 (file)
--- a/src/api.h
+++ b/src/api.h
@@ -112,7 +112,7 @@ void NeanderObject::set(int offset, v8::internal::Object* value) {
 template <typename T> static inline T ToCData(v8::internal::Object* obj) {
   STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
   return reinterpret_cast<T>(
-      reinterpret_cast<int>(v8::internal::Proxy::cast(obj)->proxy()));
+      reinterpret_cast<intptr_t>(v8::internal::Proxy::cast(obj)->proxy()));
 }
 
 
@@ -120,7 +120,7 @@ template <typename T>
 static inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) {
   STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
   return v8::internal::Factory::NewProxy(
-      reinterpret_cast<v8::internal::Address>(reinterpret_cast<int>(obj)));
+      reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
 }
 
 
index 9e63ac5..a2930f1 100644 (file)
@@ -323,8 +323,7 @@ void RelocIterator::next() {
       if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
     } else if (tag == kCodeTargetTag) {
       ReadTaggedPC();
-      if (*(reinterpret_cast<int**>(rinfo_.pc())) ==
-          reinterpret_cast<int*>(0x61)) {
+      if (*(reinterpret_cast<int*>(rinfo_.pc())) == 0x61) {
         tag = 0;
       }
       if (SetMode(RelocInfo::CODE_TARGET)) return;
index cfc29df..925c8ff 100644 (file)
@@ -57,7 +57,7 @@ class SourceCodeCache BASE_EMBEDDED {
   }
 
   void Iterate(ObjectVisitor* v) {
-    v->VisitPointer(reinterpret_cast<Object**>(&cache_));
+    v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
   }
 
 
index e3fcb7b..acdf11d 100644 (file)
@@ -610,7 +610,7 @@ void Debug::Unload() {
 
 
 void Debug::Iterate(ObjectVisitor* v) {
-#define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field)));
+#define VISIT(field) v->VisitPointer(bit_cast<Object**, Code**>(&(field)));
   VISIT(debug_break_return_entry_);
   VISIT(debug_break_return_);
 #undef VISIT
@@ -1725,7 +1725,7 @@ void DebugMessageThread::SetEventJSONFromEvent(Handle<Object> event_data) {
       }
       v8::String::Value val(json_event_string);
       Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
-                          json_event_string->Length());
+                           json_event_string->Length());
       SendMessage(str);
     } else {
       SendMessage(Vector<uint16_t>::empty());
index 94cd806..715ce1c 100644 (file)
@@ -233,16 +233,16 @@ class Debug {
   }
 
   // Support for saving/restoring registers when handling debug break calls.
-  static Address* register_address(int r) {
-    return reinterpret_cast<Address *>(&registers_[r]);
+  static Object** register_address(int r) {
+    return &registers_[r];
   }
 
   // Address of the debug break return entry code.
   static Code* debug_break_return_entry() { return debug_break_return_entry_; }
 
   // Support for getting the address of the debug break on return code.
-  static Address* debug_break_return_address() {
-    return reinterpret_cast<Address*>(&debug_break_return_);
+  static Code** debug_break_return_address() {
+    return &debug_break_return_;
   }
 
   static const int kEstimatedNofDebugInfoEntries = 16;
index 2a5cf34..26edda2 100644 (file)
@@ -463,6 +463,42 @@ F FUNCTION_CAST(Address addr) {
 #define INLINE(header) inline header
 #endif
 
+// The type-based aliasing rule allows the compiler to assume that pointers of
+// different types (for some definition of different) never alias each other.
+// Thus the following code does not work:
+//
+// float f = foo();
+// int fbits = *(int*)(&f);
+//
+// The compiler 'knows' that the int pointer can't refer to f since the types
+// don't match, so the compiler may cache f in a register, leaving random data
+// in fbits.  Using C++ style casts makes no difference, however a pointer to
+// char data is assumed to alias any other pointer.  This is the 'memcpy
+// exception'.
+//
+// Bit_cast uses the memcpy exception to move the bits from a variable of one
+// type o a variable of another type.  Of course the end result is likely to
+// be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
+// will completely optimize bit_cast away.
+//
+// There is an additional use for bit_cast.
+// Recent gccs will warn when they see casts that may result in breakage due to
+// the type-based aliasing rule.  If you have checked that there is no breakage
+// you can use bit_cast to cast one pointer type to another.  This confuses gcc
+// enough that it can no longer see that you have cast one pointer type to
+// another thus avoiding the warning.
+template <class Dest, class Source>
+inline Dest bit_cast(const Source& source) {
+  // Compile time assertion: sizeof(Dest) == sizeof(Source)
+  // A compile error here means your Dest and Source have different sizes.
+  typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1];
+
+  Dest dest;
+  memcpy(&dest, &source, sizeof(dest));
+  return dest;
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_GLOBALS_H_
index ad2c038..526f0fe 100644 (file)
@@ -2338,19 +2338,19 @@ void Heap::IterateRoots(ObjectVisitor* v) {
 
 void Heap::IterateStrongRoots(ObjectVisitor* v) {
 #define ROOT_ITERATE(type, name) \
-  v->VisitPointer(reinterpret_cast<Object**>(&name##_));
+  v->VisitPointer(bit_cast<Object**, type**>(&name##_));
   STRONG_ROOT_LIST(ROOT_ITERATE);
 #undef ROOT_ITERATE
   SYNCHRONIZE_TAG("strong_root_list");
 
 #define STRUCT_MAP_ITERATE(NAME, Name, name) \
-  v->VisitPointer(reinterpret_cast<Object**>(&name##_map_));
+  v->VisitPointer(bit_cast<Object**, Map**>(&name##_map_));
   STRUCT_LIST(STRUCT_MAP_ITERATE);
 #undef STRUCT_MAP_ITERATE
   SYNCHRONIZE_TAG("struct_map");
 
 #define SYMBOL_ITERATE(name, string) \
-  v->VisitPointer(reinterpret_cast<Object**>(&name##_));
+  v->VisitPointer(bit_cast<Object**, String**>(&name##_));
   SYMBOL_LIST(SYMBOL_ITERATE)
 #undef SYMBOL_ITERATE
   SYNCHRONIZE_TAG("symbol");
index 87db165..712e94b 100644 (file)
@@ -65,16 +65,16 @@ char* Top::Iterate(ObjectVisitor* v, char* thread_storage) {
 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field)));
 
 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
-  VISIT(thread->pending_exception_);
-  VISIT(thread->security_context_);
-  VISIT(thread->context_);
-  VISIT(thread->scheduled_exception_);
+  v->VisitPointer(&(thread->pending_exception_));
+  v->VisitPointer(bit_cast<Object**, Context**>(&(thread->security_context_)));
+  v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_)));
+  v->VisitPointer(&(thread->scheduled_exception_));
 
   for (v8::TryCatch* block = thread->try_catch_handler_;
        block != NULL;
        block = block->next_) {
-    VISIT(reinterpret_cast<Object*&>(block->exception_));
-    VISIT(reinterpret_cast<Object*&>(block->message_));
+    v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_)));
+    v->VisitPointer(bit_cast<Object**, void**>(&(block->message_)));
   }
 
   // Iterate over pointers on native execution stack.