'gcc': {
'all': {
'DIALECTFLAGS': ['-ansi'],
- 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS',
- '-fno-strict-aliasing'],
+ 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LIBS': ['pthread']
},
'CPPDEFINES': ['ENABLE_DISASSEMBLER', 'DEBUG']
},
'mode:release': {
- 'CCFLAGS': ['-O9']
+ 'CCFLAGS': ['-O3']
},
'wordsize:64': {
'CCFLAGS': ['-m32'],
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()));
}
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)));
}
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;
}
void Iterate(ObjectVisitor* v) {
- v->VisitPointer(reinterpret_cast<Object**>(&cache_));
+ v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
}
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
}
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());
}
// Support for saving/restoring registers when handling debug break calls.
- static Address* register_address(int r) {
- return reinterpret_cast<Address *>(®isters_[r]);
+ static Object** register_address(int r) {
+ return ®isters_[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;
#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_
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");
#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.