Allow gcc to use strict-aliasing rules to control pointer aliasing when

optimizing.  Obfuscate a few casts with bit_cast to avoid warnings from
gcc.
Review URL: http://codereview.chromium.org/6236

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@428 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2008-10-03 13:11:19 +00:00
parent 43783fa236
commit 70fa44ecea
7 changed files with 48 additions and 13 deletions

View 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'],

View File

@ -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)));
}

View 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_));
}

View 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());

View 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;

View 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_

View File

@ -2350,7 +2350,7 @@ void Heap::IterateStrongRoots(ObjectVisitor* v) {
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");