Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Unified Diff: src/ia32/macro-assembler-ia32.cc

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/macro-assembler-ia32-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/macro-assembler-ia32.cc
===================================================================
--- src/ia32/macro-assembler-ia32.cc (revision 7948)
+++ src/ia32/macro-assembler-ia32.cc (working copy)
@@ -94,7 +94,7 @@
void MacroAssembler::RememberedSetHelper(Register addr,
Register scratch,
SaveFPRegsMode save_fp) {
- NearLabel done;
+ Label done;
// Load store buffer top.
ExternalReference store_buffer =
ExternalReference::store_buffer_top(isolate());
@@ -108,7 +108,7 @@
// Call stub on end of buffer.
// Check for end of buffer.
test(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit));
- j(equal, &done);
+ j(equal, &done, Label::kNear);
StoreBufferOverflowStub store_buffer_overflow =
StoreBufferOverflowStub(save_fp);
CallStub(&store_buffer_overflow);
@@ -116,6 +116,63 @@
}
+void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
+ XMMRegister scratch_reg,
+ Register result_reg) {
+ Label done;
+ ExternalReference zero_ref = ExternalReference::address_of_zero();
+ movdbl(scratch_reg, Operand::StaticVariable(zero_ref));
+ Set(result_reg, Immediate(0));
+ ucomisd(input_reg, scratch_reg);
+ j(below, &done, Label::kNear);
+ ExternalReference half_ref = ExternalReference::address_of_one_half();
+ movdbl(scratch_reg, Operand::StaticVariable(half_ref));
+ addsd(scratch_reg, input_reg);
+ cvttsd2si(result_reg, Operand(scratch_reg));
+ test(result_reg, Immediate(0xFFFFFF00));
+ j(zero, &done, Label::kNear);
+ Set(result_reg, Immediate(255));
+ bind(&done);
+}
+
+
+void MacroAssembler::ClampUint8(Register reg) {
+ Label done;
+ test(reg, Immediate(0xFFFFFF00));
+ j(zero, &done, Label::kNear);
+ setcc(negative, reg); // 1 if negative, 0 if positive.
+ dec_b(reg); // 0 if negative, 255 if positive.
+ bind(&done);
+}
+
+
+void MacroAssembler::InNewSpace(Register object,
+ Register scratch,
+ Condition cc,
+ Label* branch,
+ Label::Distance branch_near) {
+ ASSERT(cc == equal || cc == not_equal);
+ if (Serializer::enabled()) {
+ // Can't do arithmetic on external references if it might get serialized.
+ mov(scratch, Operand(object));
+ // The mask isn't really an address. We load it as an external reference in
+ // case the size of the new space is different between the snapshot maker
+ // and the running system.
+ and_(Operand(scratch),
+ Immediate(ExternalReference::new_space_mask(isolate())));
+ cmp(Operand(scratch),
+ Immediate(ExternalReference::new_space_start(isolate())));
+ j(cc, branch, branch_near);
+ } else {
+ int32_t new_space_start = reinterpret_cast<int32_t>(
+ ExternalReference::new_space_start(isolate()).address());
+ lea(scratch, Operand(object, -new_space_start));
+ and_(scratch, isolate()->heap()->NewSpaceMask());
+ j(cc, branch, branch_near);
+ }
+}
+
+
void MacroAssembler::RecordWriteArray(Register object,
Register value,
Register index,
@@ -124,7 +181,7 @@
SmiCheck smi_check) {
// First, check if a write barrier is even needed. The tests below
// catch stores of Smis.
- NearLabel done;
+ Label done;
// Skip barrier if writing a smi.
if (smi_check == INLINE_SMI_CHECK) {
@@ -138,6 +195,8 @@
// into an array of words.
ASSERT_EQ(1, kSmiTagSize);
ASSERT_EQ(0, kSmiTag);
+ test(value, Immediate(kSmiTagMask));
+ j(zero, &done, Label::kNear);
Register dst = index;
lea(dst, Operand(object, index, times_half_pointer_size,
FixedArray::kHeaderSize - kHeapObjectTag));
@@ -165,13 +224,13 @@
SmiCheck smi_check) {
// First, check if a write barrier is even needed. The tests below
// catch stores of Smis.
- NearLabel done;
+ Label done;
// Skip barrier if writing a smi.
if (smi_check == INLINE_SMI_CHECK) {
ASSERT_EQ(0, kSmiTag);
test(value, Immediate(kSmiTagMask));
- j(zero, &done);
+ j(zero, &done, Label::kNear);
}
// Although the object register is tagged, the offset is relative to the start
@@ -180,9 +239,9 @@
lea(dst, FieldOperand(object, offset));
if (emit_debug_code()) {
- NearLabel ok;
+ Label ok;
test_b(Operand(dst), (1 << kPointerSizeLog2) - 1);
- j(zero, &ok);
+ j(zero, &ok, Label::kNear);
int3();
bind(&ok);
}
@@ -219,34 +278,36 @@
}
if (FLAG_debug_code) {
- NearLabel ok;
+ Label ok;
cmp(value, Operand(address, 0));
- j(equal, &ok);
- Abort("Registers did not match in write barrier");
+ j(equal, &ok, Label::kNear);
+ int3();
bind(&ok);
}
// First, check if a write barrier is even needed. The tests below
// catch stores of Smis and stores into young gen.
- NearLabel done;
+ Label done;
if (smi_check == INLINE_SMI_CHECK) {
// Skip barrier if writing a smi.
ASSERT_EQ(0, kSmiTag);
test(value, Immediate(kSmiTagMask));
- j(zero, &done);
+ j(zero, &done, Label::kNear);
}
CheckPageFlag(value,
value, // Used as scratch.
MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING,
zero,
- &done);
+ &done,
+ Label::kNear);
CheckPageFlag(object,
value, // Used as scratch.
MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING,
zero,
- &done);
+ &done,
+ Label::kNear);
RecordWriteStub stub(object, value, address, emit_remembered_set, fp_mode);
CallStub(&stub);
@@ -274,7 +335,7 @@
void MacroAssembler::Set(Register dst, const Immediate& x) {
if (x.is_zero()) {
- xor_(dst, Operand(dst)); // shorter than mov
+ xor_(dst, Operand(dst)); // Shorter than mov.
} else {
mov(dst, x);
}
@@ -286,6 +347,33 @@
}
+bool MacroAssembler::IsUnsafeImmediate(const Immediate& x) {
+ static const int kMaxImmediateBits = 17;
+ if (x.rmode_ != RelocInfo::NONE) return false;
+ return !is_intn(x.x_, kMaxImmediateBits);
+}
+
+
+void MacroAssembler::SafeSet(Register dst, const Immediate& x) {
+ if (IsUnsafeImmediate(x) && jit_cookie() != 0) {
+ Set(dst, Immediate(x.x_ ^ jit_cookie()));
+ xor_(dst, jit_cookie());
+ } else {
+ Set(dst, x);
+ }
+}
+
+
+void MacroAssembler::SafePush(const Immediate& x) {
+ if (IsUnsafeImmediate(x) && jit_cookie() != 0) {
+ push(Immediate(x.x_ ^ jit_cookie()));
+ xor_(Operand(esp, 0), Immediate(jit_cookie()));
+ } else {
+ push(x);
+ }
+}
+
+
void MacroAssembler::CmpObjectType(Register heap_object,
InstanceType type,
Register map) {
@@ -303,16 +391,30 @@
void MacroAssembler::CheckMap(Register obj,
Handle<Map> map,
Label* fail,
- bool is_heap_object) {
- if (!is_heap_object) {
- test(obj, Immediate(kSmiTagMask));
- j(zero, fail);
+ SmiCheckType smi_check_type) {
+ if (smi_check_type == DONT_DO_SMI_CHECK) {
+ JumpIfSmi(obj, fail);
}
cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map));
j(not_equal, fail);
}
+void MacroAssembler::DispatchMap(Register obj,
+ Handle<Map> map,
+ Handle<Code> success,
+ SmiCheckType smi_check_type) {
+ Label fail;
+ if (smi_check_type == DONT_DO_SMI_CHECK) {
+ JumpIfSmi(obj, &fail);
+ }
+ cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map));
+ j(equal, success);
+
+ bind(&fail);
+}
+
+
Condition MacroAssembler::IsObjectStringType(Register heap_object,
Register map,
Register instance_type) {
@@ -594,9 +696,9 @@
// not NULL. The frame pointer is NULL in the exception handler of
// a JS entry frame.
Set(esi, Immediate(0)); // Tentatively set context pointer to NULL.
- NearLabel skip;
+ Label skip;
cmp(ebp, 0);
- j(equal, &skip, not_taken);
+ j(equal, &skip, Label::kNear);
mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
bind(&skip);
@@ -621,12 +723,12 @@
mov(esp, Operand::StaticVariable(handler_address));
// Unwind the handlers until the ENTRY handler is found.
- NearLabel loop, done;
+ Label loop, done;
bind(&loop);
// Load the type of the current stack handler.
const int kStateOffset = StackHandlerConstants::kStateOffset;
cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY));
- j(equal, &done);
+ j(equal, &done, Label::kNear);
// Fetch the next handler in the list.
const int kNextOffset = StackHandlerConstants::kNextOffset;
mov(esp, Operand(esp, kNextOffset));
@@ -697,7 +799,7 @@
// Check if both contexts are the same.
cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
- j(equal, &same_contexts, taken);
+ j(equal, &same_contexts);
// Compare security tokens, save holder_reg on the stack so we can use it
// as a temporary register.
@@ -727,7 +829,7 @@
mov(scratch, FieldOperand(scratch, token_offset));
cmp(scratch, FieldOperand(holder_reg, token_offset));
pop(holder_reg);
- j(not_equal, miss, not_taken);
+ j(not_equal, miss);
bind(&same_contexts);
}
@@ -815,9 +917,9 @@
mov(top_reg, result);
}
add(Operand(top_reg), Immediate(object_size));
- j(carry, gc_required, not_taken);
+ j(carry, gc_required);
cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit));
- j(above, gc_required, not_taken);
+ j(above, gc_required);
// Update allocation top.
UpdateAllocationTopHelper(top_reg, scratch);
@@ -914,9 +1016,9 @@
mov(result_end, object_size);
}
add(result_end, Operand(result));
- j(carry, gc_required, not_taken);
+ j(carry, gc_required);
cmp(result_end, Operand::StaticVariable(new_space_allocation_limit));
- j(above, gc_required, not_taken);
+ j(above, gc_required);
// Tag result if requested.
if ((flags & TAG_OBJECT) != 0) {
@@ -1145,9 +1247,9 @@
Label* then_label) {
Label ok;
test(result, Operand(result));
- j(not_zero, &ok, taken);
+ j(not_zero, &ok);
test(op, Operand(op));
- j(sign, then_label, not_taken);
+ j(sign, then_label);
bind(&ok);
}
@@ -1159,10 +1261,10 @@
Label* then_label) {
Label ok;
test(result, Operand(result));
- j(not_zero, &ok, taken);
+ j(not_zero, &ok);
mov(scratch, Operand(op1));
or_(scratch, Operand(op2));
- j(sign, then_label, not_taken);
+ j(sign, then_label);
bind(&ok);
}
@@ -1173,17 +1275,17 @@
Label* miss) {
// Check that the receiver isn't a smi.
test(function, Immediate(kSmiTagMask));
- j(zero, miss, not_taken);
+ j(zero, miss);
// Check that the function really is a function.
CmpObjectType(function, JS_FUNCTION_TYPE, result);
- j(not_equal, miss, not_taken);
+ j(not_equal, miss);
// Make sure that the function has an instance prototype.
Label non_instance;
movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset));
test(scratch, Immediate(1 << Map::kHasNonInstancePrototype));
- j(not_zero, &non_instance, not_taken);
+ j(not_zero, &non_instance);
// Get the prototype or initial map from the function.
mov(result,
@@ -1193,7 +1295,7 @@
// simply miss the cache instead. This will allow us to allocate a
// prototype object on-demand in the runtime system.
cmp(Operand(result), Immediate(isolate()->factory()->the_hole_value()));
- j(equal, miss, not_taken);
+ j(equal, miss);
// If the function does not have an initial map, we're done.
Label done;
@@ -1215,7 +1317,8 @@
void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
- ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
+ // ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
+ // TODO(gc): Fix this!
call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
}
@@ -1473,7 +1576,7 @@
// Check if the result handle holds 0.
test(eax, Operand(eax));
- j(zero, &empty_handle, not_taken);
+ j(zero, &empty_handle);
// It was non-zero. Dereference to get the result value.
mov(eax, Operand(eax, 0));
bind(&prologue);
@@ -1483,7 +1586,7 @@
sub(Operand::StaticVariable(level_address), Immediate(1));
Assert(above_equal, "Invalid HandleScope level");
cmp(edi, Operand::StaticVariable(limit_address));
- j(not_equal, &delete_allocated_handles, not_taken);
+ j(not_equal, &delete_allocated_handles);
bind(&leave_exit_frame);
// Check if the function scheduled an exception.
@@ -1491,7 +1594,7 @@
ExternalReference::scheduled_exception_address(isolate());
cmp(Operand::StaticVariable(scheduled_exception_address),
Immediate(isolate()->factory()->the_hole_value()));
- j(not_equal, &promote_scheduled_exception, not_taken);
+ j(not_equal, &promote_scheduled_exception);
LeaveApiExitFrame();
ret(stack_space * kPointerSize);
bind(&promote_scheduled_exception);
@@ -1542,8 +1645,9 @@
const ParameterCount& actual,
Handle<Code> code_constant,
const Operand& code_operand,
- NearLabel* done,
+ Label* done,
InvokeFlag flag,
+ Label::Distance done_near,
const CallWrapper& call_wrapper) {
bool definitely_matches = false;
Label invoke;
@@ -1597,7 +1701,7 @@
call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
call(adaptor, RelocInfo::CODE_TARGET);
call_wrapper.AfterCall();
- jmp(done);
+ jmp(done, done_near);
} else {
jmp(adaptor, RelocInfo::CODE_TARGET);
}
@@ -1611,9 +1715,9 @@
const ParameterCount& actual,
InvokeFlag flag,
const CallWrapper& call_wrapper) {
- NearLabel done;
+ Label done;
InvokePrologue(expected, actual, Handle<Code>::null(), code,
- &done, flag, call_wrapper);
+ &done, flag, Label::kNear, call_wrapper);
if (flag == CALL_FUNCTION) {
call_wrapper.BeforeCall(CallSize(code));
call(code);
@@ -1632,9 +1736,10 @@
RelocInfo::Mode rmode,
InvokeFlag flag,
const CallWrapper& call_wrapper) {
- NearLabel done;
+ Label done;
Operand dummy(eax);
- InvokePrologue(expected, actual, code, dummy, &done, flag, call_wrapper);
+ InvokePrologue(expected, actual, code, dummy, &done, flag, Label::kNear,
+ call_wrapper);
if (flag == CALL_FUNCTION) {
call_wrapper.BeforeCall(CallSize(code, rmode));
call(code, rmode);
@@ -1765,7 +1870,7 @@
mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
if (emit_debug_code()) {
Label ok, fail;
- CheckMap(map, isolate()->factory()->meta_map(), &fail, false);
+ CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK);
jmp(&ok);
bind(&fail);
Abort("Global functions must have initial map");
@@ -1929,7 +2034,7 @@
void MacroAssembler::Check(Condition cc, const char* msg) {
Label L;
- j(cc, &L, taken);
+ j(cc, &L);
Abort(msg);
// will not return here
bind(&L);
@@ -1978,59 +2083,6 @@
}
-void MacroAssembler::JumpIfNotNumber(Register reg,
- TypeInfo info,
- Label* on_not_number) {
- if (emit_debug_code()) AbortIfSmi(reg);
- if (!info.IsNumber()) {
- cmp(FieldOperand(reg, HeapObject::kMapOffset),
- isolate()->factory()->heap_number_map());
- j(not_equal, on_not_number);
- }
-}
-
-
-void MacroAssembler::ConvertToInt32(Register dst,
- Register source,
- Register scratch,
- TypeInfo info,
- Label* on_not_int32) {
- if (emit_debug_code()) {
- AbortIfSmi(source);
- AbortIfNotNumber(source);
- }
- if (info.IsInteger32()) {
- cvttsd2si(dst, FieldOperand(source, HeapNumber::kValueOffset));
- } else {
- Label done;
- bool push_pop = (scratch.is(no_reg) && dst.is(source));
- ASSERT(!scratch.is(source));
- if (push_pop) {
- push(dst);
- scratch = dst;
- }
- if (scratch.is(no_reg)) scratch = dst;
- cvttsd2si(scratch, FieldOperand(source, HeapNumber::kValueOffset));
- cmp(scratch, 0x80000000u);
- if (push_pop) {
- j(not_equal, &done);
- pop(dst);
- jmp(on_not_int32);
- } else {
- j(equal, on_not_int32);
- }
-
- bind(&done);
- if (push_pop) {
- add(Operand(esp), Immediate(kPointerSize)); // Pop.
- }
- if (!scratch.is(dst)) {
- mov(dst, scratch);
- }
- }
-}
-
-
void MacroAssembler::LoadPowerOf2(XMMRegister dst,
Register scratch,
int power) {
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/macro-assembler-ia32-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698