Commit 0fc3dca6 authored by whesse@chromium.org's avatar whesse@chromium.org

Add test_b(Operand, immediate) to ia32 assembler, and use it where possible. ...

Add test_b(Operand, immediate) to ia32 assembler, and use it where possible.  Improve comparison to a constant one-character string.  Use CmpInstanceType in more places on ia32.  Add IsObjectJSObjectType and IsInstanceJSObjectType to ia32 macro assembler, using a single branch for a range test.
Review URL: http://codereview.chromium.org/2586001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4795 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 723bed31
......@@ -1328,6 +1328,15 @@ void Assembler::test(const Operand& op, const Immediate& imm) {
}
void Assembler::test_b(const Operand& op, uint8_t imm8) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0xF6);
emit_operand(eax, op);
EMIT(imm8);
}
void Assembler::xor_(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
......
......@@ -637,6 +637,7 @@ class Assembler : public Malloced {
void test(Register reg, const Operand& op);
void test_b(Register reg, const Operand& op);
void test(const Operand& op, const Immediate& imm);
void test_b(const Operand& op, uint8_t imm8);
void xor_(Register dst, int32_t imm32);
void xor_(Register dst, const Operand& src);
......
......@@ -331,10 +331,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// If the type of the result (stored in its map) is less than
// FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
__ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ cmp(ecx, FIRST_JS_OBJECT_TYPE);
__ j(greater_equal, &exit, not_taken);
__ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
__ j(above_equal, &exit, not_taken);
// Throw away the result of the constructor invocation and use the
// on-stack receiver as the result.
......@@ -469,11 +467,11 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ cmp(ebx, Factory::undefined_value());
__ j(equal, &use_global_receiver);
// We don't use IsObjectJSObjectType here because we jump on success.
__ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ cmp(ecx, FIRST_JS_OBJECT_TYPE);
__ j(below, &convert_to_object);
__ cmp(ecx, LAST_JS_OBJECT_TYPE);
__ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE));
__ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
__ j(below_equal, &shift_arguments);
__ bind(&convert_to_object);
......@@ -617,12 +615,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// If given receiver is already a JavaScript object then there's no
// reason for converting it.
// We don't use IsObjectJSObjectType here because we jump on success.
__ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
__ cmp(ecx, FIRST_JS_OBJECT_TYPE);
__ j(less, &call_to_object);
__ cmp(ecx, LAST_JS_OBJECT_TYPE);
__ j(less_equal, &push_receiver);
__ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE));
__ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
__ j(below_equal, &push_receiver);
// Convert the receiver to an object.
__ bind(&call_to_object);
......
This diff is collapsed.
......@@ -315,8 +315,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
// Check bit field.
__ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
__ test(ebx, Immediate(kSlowCaseBitFieldMask));
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), kSlowCaseBitFieldMask);
__ j(not_zero, &slow, not_taken);
// Check that the object is some kind of JS object EXCEPT JS Value type.
// In the case that the object is a value-wrapper object,
......@@ -410,9 +409,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// Is the string a symbol?
// ecx: key map.
__ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceTypeOffset));
ASSERT(kSymbolTag != 0);
__ test(ebx, Immediate(kIsSymbolMask));
__ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kIsSymbolMask);
__ j(zero, &slow, not_taken);
// If the receiver is a fast-case object, check the keyed lookup
......@@ -564,8 +562,8 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
// Check that the receiver does not require access checks. We need
// to check this explicitly since this generic stub does not perform
// map checks.
__ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
__ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
__ j(not_zero, &slow, not_taken);
__ CmpInstanceType(ecx, JS_OBJECT_TYPE);
......@@ -754,8 +752,8 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
__ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
// Check that the receiver does not require access checks. We need
// to do this because this generic stub does not perform map checks.
__ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset));
__ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
__ test_b(FieldOperand(edi, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
__ j(not_zero, &slow, not_taken);
// Check that the key is a smi.
__ test(ecx, Immediate(kSmiTagMask));
......@@ -872,8 +870,8 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
__ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
// Check that the receiver does not require access checks. We need
// to do this because this generic stub does not perform map checks.
__ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset));
__ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
__ test_b(FieldOperand(edi, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
__ j(not_zero, &slow);
// Check that the key is a smi.
__ test(ecx, Immediate(kSmiTagMask));
......@@ -1179,8 +1177,8 @@ void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
// Accessing global object: Load and invoke.
__ bind(&global_object);
// Check that the global object does not require access checks.
__ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
__ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
__ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
__ j(not_equal, &miss, not_taken);
GenerateNormalHelper(masm, argc, true, &miss);
......@@ -1191,8 +1189,8 @@ void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
__ j(equal, &global_proxy, not_taken);
// Check that the non-global, non-global-proxy object does not
// require access checks.
__ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
__ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
__ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
__ j(not_equal, &miss, not_taken);
__ bind(&invoke);
GenerateNormalHelper(masm, argc, false, &miss);
......@@ -1308,8 +1306,8 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
__ j(equal, &global, not_taken);
// Check for non-global object that requires access check.
__ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
__ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
__ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
__ j(not_zero, &miss, not_taken);
// Search the dictionary placing the result in eax.
......
......@@ -296,6 +296,25 @@ Condition MacroAssembler::IsObjectStringType(Register heap_object,
}
void MacroAssembler::IsObjectJSObjectType(Register heap_object,
Register map,
Register scratch,
Label* fail) {
mov(map, FieldOperand(heap_object, HeapObject::kMapOffset));
IsInstanceJSObjectType(map, scratch, fail);
}
void MacroAssembler::IsInstanceJSObjectType(Register map,
Register scratch,
Label* fail) {
movzx_b(scratch, FieldOperand(map, Map::kInstanceTypeOffset));
sub(Operand(scratch), Immediate(FIRST_JS_OBJECT_TYPE));
cmp(scratch, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
j(above, fail);
}
void MacroAssembler::FCmp() {
if (CpuFeatures::IsSupported(CMOV)) {
fucomip();
......
......@@ -188,6 +188,18 @@ class MacroAssembler: public Assembler {
Register map,
Register instance_type);
// Check if a heap object's type is in the JSObject range, not including
// JSFunction. The object's map will be loaded in the map register.
// Any or all of the three registers may be the same.
// The contents of the scratch register will always be overwritten.
void IsObjectJSObjectType(Register heap_object,
Register map,
Register scratch,
Label* fail);
// The contents of the scratch register will be overwritten.
void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
// FCmp is similar to integer cmp, but requires unsigned
// jcc instructions (je, ja, jae, jb, jbe, je, and jz).
void FCmp();
......
......@@ -1520,9 +1520,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
__ jmp(&miss);
} else {
// Check that the object is a string or a symbol.
__ mov(eax, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
__ cmp(eax, FIRST_NONSTRING_TYPE);
__ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax);
__ j(above_equal, &miss, not_taken);
// Check that the maps starting from the prototype haven't changed.
GenerateLoadGlobalFunctionPrototype(masm(),
......
......@@ -7476,7 +7476,7 @@ Result CodeGenerator::EmitKeyedLoad() {
__ bind(deferred->patch_site());
// Use masm-> here instead of the double underscore macro since extra
// coverage code can interfere with the patching. Do not use a load
// from the root away to load null_value, since the load must be patched
// from the root array to load null_value, since the load must be patched
// with the expected receiver map, which is not in the root array.
masm_->movq(kScratchRegister, Factory::null_value(),
RelocInfo::EMBEDDED_OBJECT);
......
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