Fix issues with compiling V8 with LLVM Clang

Added this-> in some places where accessing a method on a templated base class.

Added #include <strings.h> for bit_cast, moved it to utils.h and renamed it to BitCast.

Patch by Evan Martin <evan@chromium.org>, see http://codereview.chromium.org/894001 and http://codereview.chromium.org/888003
Review URL: http://codereview.chromium.org/888005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4111 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2010-03-12 10:20:01 +00:00
parent 44d0112b71
commit 16bfc31317
13 changed files with 71 additions and 69 deletions

View File

@ -280,9 +280,9 @@ void MacroAssembler::RecordWrite(Register object, Register offset,
// Clobber all input registers when running with the debug-code flag
// turned on to provoke errors.
if (FLAG_debug_code) {
mov(object, Operand(bit_cast<int32_t>(kZapValue)));
mov(offset, Operand(bit_cast<int32_t>(kZapValue)));
mov(scratch, Operand(bit_cast<int32_t>(kZapValue)));
mov(object, Operand(BitCast<int32_t>(kZapValue)));
mov(offset, Operand(BitCast<int32_t>(kZapValue)));
mov(scratch, Operand(BitCast<int32_t>(kZapValue)));
}
}

View File

@ -55,7 +55,7 @@ class SourceCodeCache BASE_EMBEDDED {
}
void Iterate(ObjectVisitor* v) {
v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
v->VisitPointer(BitCast<Object**, FixedArray**>(&cache_));
}

View File

@ -803,7 +803,7 @@ void Debug::PreemptionWhileInDebugger() {
void Debug::Iterate(ObjectVisitor* v) {
v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_)));
v->VisitPointer(BitCast<Object**, Code**>(&(debug_break_return_)));
}

View File

@ -34,8 +34,8 @@ namespace v8 {
namespace internal {
// We assume that doubles and uint64_t have the same endianness.
static uint64_t double_to_uint64(double d) { return bit_cast<uint64_t>(d); }
static double uint64_to_double(uint64_t d64) { return bit_cast<double>(d64); }
static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
// Helper functions for doubles.
class Double {

View File

@ -317,7 +317,7 @@ class Factory : public AllStatic {
#define ROOT_ACCESSOR(type, name, camel_name) \
static inline Handle<type> name() { \
return Handle<type>(bit_cast<type**, Object**>( \
return Handle<type>(BitCast<type**, Object**>( \
&Heap::roots_[Heap::k##camel_name##RootIndex])); \
}
ROOT_LIST(ROOT_ACCESSOR)
@ -325,7 +325,7 @@ class Factory : public AllStatic {
#define SYMBOL_ACCESSOR(name, str) \
static inline Handle<String> name() { \
return Handle<String>(bit_cast<String**, Object**>( \
return Handle<String>(BitCast<String**, Object**>( \
&Heap::roots_[Heap::k##name##RootIndex])); \
}
SYMBOL_LIST(SYMBOL_ACCESSOR)

View File

@ -574,42 +574,6 @@ 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 of 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;
}
// Feature flags bit positions. They are mostly based on the CPUID spec.
// (We assign CPUID itself to one of the currently reserved bits --
// feel free to change this if needed.)

View File

@ -3399,7 +3399,7 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
v->Synchronize("strong_root_list");
v->VisitPointer(bit_cast<Object**, String**>(&hidden_symbol_));
v->VisitPointer(BitCast<Object**, String**>(&hidden_symbol_));
v->Synchronize("symbol");
Bootstrapper::Iterate(v);

View File

@ -186,9 +186,9 @@ void MacroAssembler::RecordWrite(Register object, int offset,
// Clobber all input registers when running with the debug-code flag
// turned on to provoke errors.
if (FLAG_debug_code) {
mov(object, Immediate(bit_cast<int32_t>(kZapValue)));
mov(value, Immediate(bit_cast<int32_t>(kZapValue)));
mov(scratch, Immediate(bit_cast<int32_t>(kZapValue)));
mov(object, Immediate(BitCast<int32_t>(kZapValue)));
mov(value, Immediate(BitCast<int32_t>(kZapValue)));
mov(scratch, Immediate(BitCast<int32_t>(kZapValue)));
}
}

View File

@ -31,7 +31,7 @@
#include "disasm.h"
#include "assembler.h"
#include "globals.h" // Need the bit_cast
#include "globals.h" // Need the BitCast
#include "mips/constants-mips.h"
#include "mips/simulator-mips.h"
@ -604,7 +604,7 @@ void Simulator::set_fpu_register(int fpureg, int32_t value) {
void Simulator::set_fpu_register_double(int fpureg, double value) {
ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
*v8i::bit_cast<double*, int32_t*>(&FPUregisters_[fpureg]) = value;
*v8i::BitCast<double*, int32_t*>(&FPUregisters_[fpureg]) = value;
}
@ -625,7 +625,7 @@ int32_t Simulator::get_fpu_register(int fpureg) const {
double Simulator::get_fpu_register_double(int fpureg) const {
ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
return *v8i::bit_cast<double*, int32_t*>(
return *v8i::BitCast<double*, int32_t*>(
const_cast<int32_t*>(&FPUregisters_[fpureg]));
}
@ -901,7 +901,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
break;
case MFHC1:
fp_out = get_fpu_register_double(fs_reg);
alu_out = *v8i::bit_cast<int32_t*, double*>(&fp_out);
alu_out = *v8i::BitCast<int32_t*, double*>(&fp_out);
break;
case MTC1:
case MTHC1:

View File

@ -2154,24 +2154,24 @@ class Dictionary: public HashTable<Shape, Key> {
// Returns the value at entry.
Object* ValueAt(int entry) {
return get(HashTable<Shape, Key>::EntryToIndex(entry)+1);
return this->get(HashTable<Shape, Key>::EntryToIndex(entry)+1);
}
// Set the value for entry.
void ValueAtPut(int entry, Object* value) {
set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value);
this->set(HashTable<Shape, Key>::EntryToIndex(entry)+1, value);
}
// Returns the property details for the property at entry.
PropertyDetails DetailsAt(int entry) {
ASSERT(entry >= 0); // Not found is -1, which is not caught by get().
return PropertyDetails(
Smi::cast(get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
}
// Set the details for entry.
void DetailsAtPut(int entry, PropertyDetails value) {
set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
}
// Sorting support
@ -2194,7 +2194,7 @@ class Dictionary: public HashTable<Shape, Key> {
// Accessors for next enumeration index.
void SetNextEnumerationIndex(int index) {
fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index));
this->fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index));
}
int NextEnumerationIndex() {

View File

@ -92,15 +92,15 @@ void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
v->VisitPointer(&(thread->pending_exception_));
v->VisitPointer(&(thread->pending_message_obj_));
v->VisitPointer(
bit_cast<Object**, Script**>(&(thread->pending_message_script_)));
v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_)));
BitCast<Object**, Script**>(&(thread->pending_message_script_)));
v->VisitPointer(BitCast<Object**, Context**>(&(thread->context_)));
v->VisitPointer(&(thread->scheduled_exception_));
for (v8::TryCatch* block = thread->TryCatchHandler();
block != NULL;
block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_)));
v->VisitPointer(bit_cast<Object**, void**>(&(block->message_)));
v->VisitPointer(BitCast<Object**, void**>(&(block->exception_)));
v->VisitPointer(BitCast<Object**, void**>(&(block->message_)));
}
// Iterate over pointers on native execution stack.

View File

@ -29,6 +29,7 @@
#define V8_UTILS_H_
#include <stdlib.h>
#include <string.h>
namespace v8 {
namespace internal {
@ -396,7 +397,7 @@ class EmbeddedVector : public Vector<T> {
if (this == &rhs) return *this;
Vector<T>::operator=(rhs);
memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
set_start(buffer_);
this->set_start(buffer_);
return *this;
}
@ -599,6 +600,43 @@ static inline void MemsetPointer(T** dest, T* value, int counter) {
// Calculate 10^exponent.
int TenToThe(int exponent);
// 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 of 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 BitCast away.
//
// There is an additional use for BitCast.
// 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 BitCast 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 BitCast(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_UTILS_H_

View File

@ -197,9 +197,9 @@ void MacroAssembler::RecordWrite(Register object,
// avoid having the fast case for smis leave the registers
// unchanged.
if (FLAG_debug_code) {
movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
movq(value, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(smi_index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
}
}
@ -270,9 +270,9 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
// Clobber all input registers when running with the debug-code flag
// turned on to provoke errors.
if (FLAG_debug_code) {
movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
movq(scratch, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(smi_index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
}
}