Commit b65c24f6 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Recommit reverted change, now with fixes to make it work with gcc-4.2.

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
parent 6d8a21ee
......@@ -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'],
......
......@@ -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)));
}
......
......@@ -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;
......
......@@ -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_));
}
......
......@@ -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());
......
......@@ -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;
......
......@@ -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_
......@@ -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");
......
......@@ -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.
......
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