Fix/unify root handling in code generation.

R=danno@chromium.org

Review URL: https://codereview.chromium.org/22670004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16132 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
bmeurer@chromium.org 2013-08-09 13:43:46 +00:00
parent 201c512dc7
commit 770e6ee8b8
6 changed files with 89 additions and 71 deletions

View File

@ -375,16 +375,13 @@ void MacroAssembler::LoadRoot(Register destination,
Heap::RootListIndex index,
Condition cond) {
if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
!Heap::RootCanBeWrittenAfterInitialization(index) &&
isolate()->heap()->RootCanBeTreatedAsConstant(index) &&
!predictable_code_size()) {
Handle<Object> root(isolate()->heap()->roots_array_start()[index],
isolate());
if (!isolate()->heap()->InNewSpace(*root)) {
// The CPU supports fast immediate values, and this root will never
// change. We will load it as a relocatable immediate value.
mov(destination, Operand(root), LeaveCC, cond);
return;
}
// The CPU supports fast immediate values, and this root will never
// change. We will load it as a relocatable immediate value.
Handle<Object> root(&isolate()->heap()->roots_array_start()[index]);
mov(destination, Operand(root), LeaveCC, cond);
return;
}
ldr(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), cond);
}

View File

@ -3263,6 +3263,12 @@ bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
}
bool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) {
return !RootCanBeWrittenAfterInitialization(root_index) &&
!InNewSpace(roots_array_start()[root_index]);
}
Object* RegExpResultsCache::Lookup(Heap* heap,
String* key_string,
Object* key_pattern,

View File

@ -1615,6 +1615,8 @@ class Heap {
// Generated code can embed direct references to non-writable roots if
// they are in new space.
static bool RootCanBeWrittenAfterInitialization(RootListIndex root_index);
// Generated code can treat direct references to this root as constant.
bool RootCanBeTreatedAsConstant(RootListIndex root_index);
MUST_USE_RESULT MaybeObject* NumberToString(
Object* number, bool check_number_string_cache = true,

View File

@ -3956,11 +3956,7 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
Register scratch = scratch2;
// Load the number string cache.
ExternalReference roots_array_start =
ExternalReference::roots_array_start(masm->isolate());
__ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex));
__ mov(number_string_cache,
Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
__ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
// Make the hash mask from the length of the number string cache. It
// contains two elements (number and string) for each cache entry.
__ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
@ -5010,9 +5006,6 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
static const int8_t kCmpEdiOperandByte2 = BitCast<int8_t, uint8_t>(0x3d);
static const int8_t kMovEaxImmediateByte = BitCast<int8_t, uint8_t>(0xb8);
ExternalReference roots_array_start =
ExternalReference::roots_array_start(masm->isolate());
ASSERT_EQ(object.code(), InstanceofStub::left().code());
ASSERT_EQ(function.code(), InstanceofStub::right().code());
@ -5032,18 +5025,11 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
if (!HasCallSiteInlineCheck()) {
// Look up the function and the map in the instanceof cache.
Label miss;
__ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
__ cmp(function, Operand::StaticArray(scratch,
times_pointer_size,
roots_array_start));
__ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
__ j(not_equal, &miss, Label::kNear);
__ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex));
__ cmp(map, Operand::StaticArray(
scratch, times_pointer_size, roots_array_start));
__ CompareRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex);
__ j(not_equal, &miss, Label::kNear);
__ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
__ mov(eax, Operand::StaticArray(
scratch, times_pointer_size, roots_array_start));
__ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex);
__ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
__ bind(&miss);
}
@ -5058,12 +5044,8 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
// Update the global instanceof or call site inlined cache with the current
// map and function. The cached answer will be set when it is known below.
if (!HasCallSiteInlineCheck()) {
__ mov(scratch, Immediate(Heap::kInstanceofCacheMapRootIndex));
__ mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start),
map);
__ mov(scratch, Immediate(Heap::kInstanceofCacheFunctionRootIndex));
__ mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start),
function);
__ StoreRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex);
__ StoreRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
} else {
// The constants for the code patching are based on no push instructions
// at the call site.
@ -5097,10 +5079,8 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ bind(&is_instance);
if (!HasCallSiteInlineCheck()) {
__ Set(eax, Immediate(0));
__ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
__ mov(Operand::StaticArray(scratch,
times_pointer_size, roots_array_start), eax);
__ mov(eax, Immediate(0));
__ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
} else {
// Get return address and delta to inlined map check.
__ mov(eax, factory->true_value());
@ -5119,10 +5099,8 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ bind(&is_not_instance);
if (!HasCallSiteInlineCheck()) {
__ Set(eax, Immediate(Smi::FromInt(1)));
__ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
__ mov(Operand::StaticArray(
scratch, times_pointer_size, roots_array_start), eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
__ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
} else {
// Get return address and delta to inlined map check.
__ mov(eax, factory->false_value());
@ -5875,11 +5853,7 @@ void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
// Load the string table.
Register string_table = c2;
ExternalReference roots_array_start =
ExternalReference::roots_array_start(masm->isolate());
__ mov(scratch, Immediate(Heap::kStringTableRootIndex));
__ mov(string_table,
Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
__ LoadRoot(string_table, Heap::kStringTableRootIndex);
// Calculate capacity mask from the string table capacity.
Register mask = scratch2;
@ -5967,12 +5941,7 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register scratch) {
// hash = (seed + character) + ((seed + character) << 10);
if (Serializer::enabled()) {
ExternalReference roots_array_start =
ExternalReference::roots_array_start(masm->isolate());
__ mov(scratch, Immediate(Heap::kHashSeedRootIndex));
__ mov(scratch, Operand::StaticArray(scratch,
times_pointer_size,
roots_array_start));
__ LoadRoot(scratch, Heap::kHashSeedRootIndex);
__ SmiUntag(scratch);
__ add(scratch, character);
__ mov(hash, scratch);

View File

@ -54,6 +54,60 @@ MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
}
void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
if (isolate()->heap()->RootCanBeTreatedAsConstant(index)) {
Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
mov(destination, value);
return;
}
ExternalReference roots_array_start =
ExternalReference::roots_array_start(isolate());
mov(destination, Immediate(index));
mov(destination, Operand::StaticArray(destination,
times_pointer_size,
roots_array_start));
}
void MacroAssembler::StoreRoot(Register source,
Register scratch,
Heap::RootListIndex index) {
ASSERT(Heap::RootCanBeWrittenAfterInitialization(index));
ExternalReference roots_array_start =
ExternalReference::roots_array_start(isolate());
mov(scratch, Immediate(index));
mov(Operand::StaticArray(scratch, times_pointer_size, roots_array_start),
source);
}
void MacroAssembler::CompareRoot(Register with,
Register scratch,
Heap::RootListIndex index) {
ExternalReference roots_array_start =
ExternalReference::roots_array_start(isolate());
mov(scratch, Immediate(index));
cmp(with, Operand::StaticArray(scratch,
times_pointer_size,
roots_array_start));
}
void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
ASSERT(isolate()->heap()->RootCanBeTreatedAsConstant(index));
Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
cmp(with, value);
}
void MacroAssembler::CompareRoot(const Operand& with,
Heap::RootListIndex index) {
ASSERT(isolate()->heap()->RootCanBeTreatedAsConstant(index));
Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
cmp(with, value);
}
void MacroAssembler::InNewSpace(
Register object,
Register scratch,
@ -432,21 +486,6 @@ void MacroAssembler::SafePush(const Immediate& x) {
}
void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
// see ROOT_ACCESSOR macro in factory.h
Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
cmp(with, value);
}
void MacroAssembler::CompareRoot(const Operand& with,
Heap::RootListIndex index) {
// see ROOT_ACCESSOR macro in factory.h
Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
cmp(with, value);
}
void MacroAssembler::CmpObjectType(Register heap_object,
InstanceType type,
Register map) {

View File

@ -61,6 +61,15 @@ class MacroAssembler: public Assembler {
// macro assembler.
MacroAssembler(Isolate* isolate, void* buffer, int size);
// Operations on roots in the root-array.
void LoadRoot(Register destination, Heap::RootListIndex index);
void StoreRoot(Register source, Register scratch, Heap::RootListIndex index);
void CompareRoot(Register with, Register scratch, Heap::RootListIndex index);
// These methods can only be used with constant roots (i.e. non-writable
// and not in new space).
void CompareRoot(Register with, Heap::RootListIndex index);
void CompareRoot(const Operand& with, Heap::RootListIndex index);
// ---------------------------------------------------------------------------
// GC Support
enum RememberedSetFinalAction {
@ -362,10 +371,6 @@ class MacroAssembler: public Assembler {
void SafeSet(Register dst, const Immediate& x);
void SafePush(const Immediate& x);
// Compare against a known root, e.g. undefined, null, true, ...
void CompareRoot(Register with, Heap::RootListIndex index);
void CompareRoot(const Operand& with, Heap::RootListIndex index);
// Compare object type for heap object.
// Incoming register is heap_object and outgoing register is map.
void CmpObjectType(Register heap_object, InstanceType type, Register map);