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 |