| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2308 __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE)); | 2308 __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE)); |
| 2309 } else { | 2309 } else { |
| 2310 __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE)); | 2310 __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE)); |
| 2311 } | 2311 } |
| 2312 | 2312 |
| 2313 // temp now contains the constructor function. Grab the | 2313 // temp now contains the constructor function. Grab the |
| 2314 // instance class name from there. | 2314 // instance class name from there. |
| 2315 __ lw(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset)); | 2315 __ lw(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset)); |
| 2316 __ lw(temp, FieldMemOperand(temp, | 2316 __ lw(temp, FieldMemOperand(temp, |
| 2317 SharedFunctionInfo::kInstanceClassNameOffset)); | 2317 SharedFunctionInfo::kInstanceClassNameOffset)); |
| 2318 // The class name we are testing against is a symbol because it's a literal. | 2318 // The class name we are testing against is internalized since it's a literal. |
| 2319 // The name in the constructor is a symbol because of the way the context is | 2319 // The name in the constructor is internalized because of the way the context |
| 2320 // booted. This routine isn't expected to work for random API-created | 2320 // is booted. This routine isn't expected to work for random API-created |
| 2321 // classes and it doesn't have to because you can't access it with natives | 2321 // classes and it doesn't have to because you can't access it with natives |
| 2322 // syntax. Since both sides are symbols it is sufficient to use an identity | 2322 // syntax. Since both sides are internalized it is sufficient to use an |
| 2323 // comparison. | 2323 // identity comparison. |
| 2324 | 2324 |
| 2325 // End with the address of this class_name instance in temp register. | 2325 // End with the address of this class_name instance in temp register. |
| 2326 // On MIPS, the caller must do the comparison with Handle<String>class_name. | 2326 // On MIPS, the caller must do the comparison with Handle<String>class_name. |
| 2327 } | 2327 } |
| 2328 | 2328 |
| 2329 | 2329 |
| 2330 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { | 2330 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { |
| 2331 Register input = ToRegister(instr->value()); | 2331 Register input = ToRegister(instr->value()); |
| 2332 Register temp = scratch0(); | 2332 Register temp = scratch0(); |
| 2333 Register temp2 = ToRegister(instr->temp()); | 2333 Register temp2 = ToRegister(instr->temp()); |
| (...skipping 3353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5687 Label* false_label, | 5687 Label* false_label, |
| 5688 Register input, | 5688 Register input, |
| 5689 Handle<String> type_name, | 5689 Handle<String> type_name, |
| 5690 Register& cmp1, | 5690 Register& cmp1, |
| 5691 Operand& cmp2) { | 5691 Operand& cmp2) { |
| 5692 // This function utilizes the delay slot heavily. This is used to load | 5692 // This function utilizes the delay slot heavily. This is used to load |
| 5693 // values that are always usable without depending on the type of the input | 5693 // values that are always usable without depending on the type of the input |
| 5694 // register. | 5694 // register. |
| 5695 Condition final_branch_condition = kNoCondition; | 5695 Condition final_branch_condition = kNoCondition; |
| 5696 Register scratch = scratch0(); | 5696 Register scratch = scratch0(); |
| 5697 if (type_name->Equals(heap()->number_symbol())) { | 5697 if (type_name->Equals(heap()->number_string())) { |
| 5698 __ JumpIfSmi(input, true_label); | 5698 __ JumpIfSmi(input, true_label); |
| 5699 __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); | 5699 __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 5700 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 5700 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
| 5701 cmp1 = input; | 5701 cmp1 = input; |
| 5702 cmp2 = Operand(at); | 5702 cmp2 = Operand(at); |
| 5703 final_branch_condition = eq; | 5703 final_branch_condition = eq; |
| 5704 | 5704 |
| 5705 } else if (type_name->Equals(heap()->string_symbol())) { | 5705 } else if (type_name->Equals(heap()->string_string())) { |
| 5706 __ JumpIfSmi(input, false_label); | 5706 __ JumpIfSmi(input, false_label); |
| 5707 __ GetObjectType(input, input, scratch); | 5707 __ GetObjectType(input, input, scratch); |
| 5708 __ Branch(USE_DELAY_SLOT, false_label, | 5708 __ Branch(USE_DELAY_SLOT, false_label, |
| 5709 ge, scratch, Operand(FIRST_NONSTRING_TYPE)); | 5709 ge, scratch, Operand(FIRST_NONSTRING_TYPE)); |
| 5710 // input is an object so we can load the BitFieldOffset even if we take the | 5710 // input is an object so we can load the BitFieldOffset even if we take the |
| 5711 // other branch. | 5711 // other branch. |
| 5712 __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); | 5712 __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); |
| 5713 __ And(at, at, 1 << Map::kIsUndetectable); | 5713 __ And(at, at, 1 << Map::kIsUndetectable); |
| 5714 cmp1 = at; | 5714 cmp1 = at; |
| 5715 cmp2 = Operand(zero_reg); | 5715 cmp2 = Operand(zero_reg); |
| 5716 final_branch_condition = eq; | 5716 final_branch_condition = eq; |
| 5717 | 5717 |
| 5718 } else if (type_name->Equals(heap()->boolean_symbol())) { | 5718 } else if (type_name->Equals(heap()->boolean_string())) { |
| 5719 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 5719 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
| 5720 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); | 5720 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); |
| 5721 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 5721 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
| 5722 cmp1 = at; | 5722 cmp1 = at; |
| 5723 cmp2 = Operand(input); | 5723 cmp2 = Operand(input); |
| 5724 final_branch_condition = eq; | 5724 final_branch_condition = eq; |
| 5725 | 5725 |
| 5726 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) { | 5726 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |
| 5727 __ LoadRoot(at, Heap::kNullValueRootIndex); | 5727 __ LoadRoot(at, Heap::kNullValueRootIndex); |
| 5728 cmp1 = at; | 5728 cmp1 = at; |
| 5729 cmp2 = Operand(input); | 5729 cmp2 = Operand(input); |
| 5730 final_branch_condition = eq; | 5730 final_branch_condition = eq; |
| 5731 | 5731 |
| 5732 } else if (type_name->Equals(heap()->undefined_symbol())) { | 5732 } else if (type_name->Equals(heap()->undefined_string())) { |
| 5733 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 5733 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 5734 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); | 5734 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); |
| 5735 // The first instruction of JumpIfSmi is an And - it is safe in the delay | 5735 // The first instruction of JumpIfSmi is an And - it is safe in the delay |
| 5736 // slot. | 5736 // slot. |
| 5737 __ JumpIfSmi(input, false_label); | 5737 __ JumpIfSmi(input, false_label); |
| 5738 // Check for undetectable objects => true. | 5738 // Check for undetectable objects => true. |
| 5739 __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); | 5739 __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 5740 __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); | 5740 __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); |
| 5741 __ And(at, at, 1 << Map::kIsUndetectable); | 5741 __ And(at, at, 1 << Map::kIsUndetectable); |
| 5742 cmp1 = at; | 5742 cmp1 = at; |
| 5743 cmp2 = Operand(zero_reg); | 5743 cmp2 = Operand(zero_reg); |
| 5744 final_branch_condition = ne; | 5744 final_branch_condition = ne; |
| 5745 | 5745 |
| 5746 } else if (type_name->Equals(heap()->function_symbol())) { | 5746 } else if (type_name->Equals(heap()->function_string())) { |
| 5747 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 5747 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
| 5748 __ JumpIfSmi(input, false_label); | 5748 __ JumpIfSmi(input, false_label); |
| 5749 __ GetObjectType(input, scratch, input); | 5749 __ GetObjectType(input, scratch, input); |
| 5750 __ Branch(true_label, eq, input, Operand(JS_FUNCTION_TYPE)); | 5750 __ Branch(true_label, eq, input, Operand(JS_FUNCTION_TYPE)); |
| 5751 cmp1 = input; | 5751 cmp1 = input; |
| 5752 cmp2 = Operand(JS_FUNCTION_PROXY_TYPE); | 5752 cmp2 = Operand(JS_FUNCTION_PROXY_TYPE); |
| 5753 final_branch_condition = eq; | 5753 final_branch_condition = eq; |
| 5754 | 5754 |
| 5755 } else if (type_name->Equals(heap()->object_symbol())) { | 5755 } else if (type_name->Equals(heap()->object_string())) { |
| 5756 __ JumpIfSmi(input, false_label); | 5756 __ JumpIfSmi(input, false_label); |
| 5757 if (!FLAG_harmony_typeof) { | 5757 if (!FLAG_harmony_typeof) { |
| 5758 __ LoadRoot(at, Heap::kNullValueRootIndex); | 5758 __ LoadRoot(at, Heap::kNullValueRootIndex); |
| 5759 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); | 5759 __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); |
| 5760 } | 5760 } |
| 5761 // input is an object, it is safe to use GetObjectType in the delay slot. | 5761 // input is an object, it is safe to use GetObjectType in the delay slot. |
| 5762 __ GetObjectType(input, input, scratch); | 5762 __ GetObjectType(input, input, scratch); |
| 5763 __ Branch(USE_DELAY_SLOT, false_label, | 5763 __ Branch(USE_DELAY_SLOT, false_label, |
| 5764 lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 5764 lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 5765 // Still an object, so the InstanceType can be loaded. | 5765 // Still an object, so the InstanceType can be loaded. |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6038 __ Subu(scratch, result, scratch); | 6038 __ Subu(scratch, result, scratch); |
| 6039 __ lw(result, FieldMemOperand(scratch, | 6039 __ lw(result, FieldMemOperand(scratch, |
| 6040 FixedArray::kHeaderSize - kPointerSize)); | 6040 FixedArray::kHeaderSize - kPointerSize)); |
| 6041 __ bind(&done); | 6041 __ bind(&done); |
| 6042 } | 6042 } |
| 6043 | 6043 |
| 6044 | 6044 |
| 6045 #undef __ | 6045 #undef __ |
| 6046 | 6046 |
| 6047 } } // namespace v8::internal | 6047 } } // namespace v8::internal |
| OLD | NEW |