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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 __ j(zero, &ok, Label::kNear); | 153 __ j(zero, &ok, Label::kNear); |
154 // +1 for return address. | 154 // +1 for return address. |
155 int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; | 155 int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; |
156 __ mov(Operand(esp, receiver_offset), | 156 __ mov(Operand(esp, receiver_offset), |
157 Immediate(isolate()->factory()->undefined_value())); | 157 Immediate(isolate()->factory()->undefined_value())); |
158 __ bind(&ok); | 158 __ bind(&ok); |
159 } | 159 } |
160 | 160 |
161 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { | 161 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { |
162 // Move state of dynamic frame alignment into edx. | 162 // Move state of dynamic frame alignment into edx. |
163 __ mov(edx, Immediate(kNoAlignmentPadding)); | 163 __ Set(edx, Immediate(kNoAlignmentPadding)); |
164 | 164 |
165 Label do_not_pad, align_loop; | 165 Label do_not_pad, align_loop; |
166 STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); | 166 STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); |
167 // Align esp + 4 to a multiple of 2 * kPointerSize. | 167 // Align esp + 4 to a multiple of 2 * kPointerSize. |
168 __ test(esp, Immediate(kPointerSize)); | 168 __ test(esp, Immediate(kPointerSize)); |
169 __ j(not_zero, &do_not_pad, Label::kNear); | 169 __ j(not_zero, &do_not_pad, Label::kNear); |
170 __ push(Immediate(0)); | 170 __ push(Immediate(0)); |
171 __ mov(ebx, esp); | 171 __ mov(ebx, esp); |
172 __ mov(edx, Immediate(kAlignmentPaddingPushed)); | 172 __ mov(edx, Immediate(kAlignmentPaddingPushed)); |
173 // Copy arguments, receiver, and return address. | 173 // Copy arguments, receiver, and return address. |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 309 |
310 | 310 |
311 void LCodeGen::GenerateOsrPrologue() { | 311 void LCodeGen::GenerateOsrPrologue() { |
312 // Generate the OSR entry prologue at the first unknown OSR value, or if there | 312 // Generate the OSR entry prologue at the first unknown OSR value, or if there |
313 // are none, at the OSR entrypoint instruction. | 313 // are none, at the OSR entrypoint instruction. |
314 if (osr_pc_offset_ >= 0) return; | 314 if (osr_pc_offset_ >= 0) return; |
315 | 315 |
316 osr_pc_offset_ = masm()->pc_offset(); | 316 osr_pc_offset_ = masm()->pc_offset(); |
317 | 317 |
318 // Move state of dynamic frame alignment into edx. | 318 // Move state of dynamic frame alignment into edx. |
319 __ mov(edx, Immediate(kNoAlignmentPadding)); | 319 __ Set(edx, Immediate(kNoAlignmentPadding)); |
320 | 320 |
321 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { | 321 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { |
322 Label do_not_pad, align_loop; | 322 Label do_not_pad, align_loop; |
323 // Align ebp + 4 to a multiple of 2 * kPointerSize. | 323 // Align ebp + 4 to a multiple of 2 * kPointerSize. |
324 __ test(ebp, Immediate(kPointerSize)); | 324 __ test(ebp, Immediate(kPointerSize)); |
325 __ j(zero, &do_not_pad, Label::kNear); | 325 __ j(zero, &do_not_pad, Label::kNear); |
326 __ push(Immediate(0)); | 326 __ push(Immediate(0)); |
327 __ mov(ebx, esp); | 327 __ mov(ebx, esp); |
328 __ mov(edx, Immediate(kAlignmentPaddingPushed)); | 328 __ mov(edx, Immediate(kAlignmentPaddingPushed)); |
329 | 329 |
(...skipping 5614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5944 } | 5944 } |
5945 } | 5945 } |
5946 | 5946 |
5947 | 5947 |
5948 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 5948 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
5949 Register result = ToRegister(instr->result()); | 5949 Register result = ToRegister(instr->result()); |
5950 | 5950 |
5951 // TODO(3095996): Get rid of this. For now, we need to make the | 5951 // TODO(3095996): Get rid of this. For now, we need to make the |
5952 // result register contain a valid pointer because it is already | 5952 // result register contain a valid pointer because it is already |
5953 // contained in the register pointer map. | 5953 // contained in the register pointer map. |
5954 __ mov(result, Immediate(Smi::FromInt(0))); | 5954 __ Set(result, Immediate(Smi::FromInt(0))); |
5955 | 5955 |
5956 PushSafepointRegistersScope scope(this); | 5956 PushSafepointRegistersScope scope(this); |
5957 if (instr->size()->IsRegister()) { | 5957 if (instr->size()->IsRegister()) { |
5958 Register size = ToRegister(instr->size()); | 5958 Register size = ToRegister(instr->size()); |
5959 ASSERT(!size.is(result)); | 5959 ASSERT(!size.is(result)); |
5960 __ SmiTag(ToRegister(instr->size())); | 5960 __ SmiTag(ToRegister(instr->size())); |
5961 __ push(size); | 5961 __ push(size); |
5962 } else { | 5962 } else { |
5963 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5963 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
5964 __ push(Immediate(Smi::FromInt(size))); | 5964 __ push(Immediate(Smi::FromInt(size))); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6061 | 6061 |
6062 | 6062 |
6063 void LCodeGen::DoTypeof(LTypeof* instr) { | 6063 void LCodeGen::DoTypeof(LTypeof* instr) { |
6064 LOperand* input = instr->value(); | 6064 LOperand* input = instr->value(); |
6065 EmitPushTaggedOperand(input); | 6065 EmitPushTaggedOperand(input); |
6066 CallRuntime(Runtime::kTypeof, 1, instr); | 6066 CallRuntime(Runtime::kTypeof, 1, instr); |
6067 } | 6067 } |
6068 | 6068 |
6069 | 6069 |
6070 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 6070 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
6071 Register input = ToRegister(instr->value()); | 6071 switch (instr->hydrogen()->state()) { |
6072 | 6072 case HTypeofIsAndBranch::kUnKnown: { |
6073 Condition final_branch_condition = | 6073 Register input = ToRegister(instr->value()); |
6074 EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), | 6074 Condition final_branch_condition = EmitTypeofIs(instr, input); |
6075 input, instr->type_literal()); | 6075 if (final_branch_condition != no_condition) { |
6076 if (final_branch_condition != no_condition) { | 6076 EmitBranch(instr, final_branch_condition); |
6077 EmitBranch(instr, final_branch_condition); | 6077 } |
| 6078 break; |
| 6079 } |
| 6080 case HTypeofIsAndBranch::kAlwaysTrue: { |
| 6081 __ jmp(instr->TrueLabel(chunk_)); |
| 6082 break; |
| 6083 } |
| 6084 case HTypeofIsAndBranch::kAlwaysFalse: { |
| 6085 __ jmp(instr->FalseLabel(chunk_)); |
| 6086 break; |
| 6087 } |
| 6088 default: |
| 6089 UNREACHABLE(); |
6078 } | 6090 } |
6079 } | 6091 } |
6080 | 6092 |
6081 | 6093 |
6082 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 6094 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { |
6083 Label* false_label, | 6095 Label* true_label = instr->TrueLabel(chunk_); |
6084 Register input, | 6096 Label* false_label = instr->FalseLabel(chunk_); |
6085 Handle<String> type_name) { | 6097 Handle<String> type_name = instr->type_literal(); |
| 6098 int left_block = instr->TrueDestination(chunk_); |
| 6099 int right_block = instr->FalseDestination(chunk_); |
| 6100 int next_block = GetNextEmittedBlock(); |
| 6101 |
| 6102 Label::Distance true_distance = Label::kFar; |
| 6103 Label::Distance false_distance = Label::kFar; |
| 6104 if (left_block == next_block) { |
| 6105 true_distance = Label::kNear; |
| 6106 } else if (right_block == next_block) { |
| 6107 false_distance = Label::kNear; |
| 6108 } |
| 6109 |
6086 Condition final_branch_condition = no_condition; | 6110 Condition final_branch_condition = no_condition; |
6087 if (type_name->Equals(heap()->number_string())) { | 6111 if (type_name->Equals(heap()->number_string())) { |
6088 __ JumpIfSmi(input, true_label); | 6112 __ JumpIfSmi(input, true_label, true_distance); |
6089 __ cmp(FieldOperand(input, HeapObject::kMapOffset), | 6113 __ cmp(FieldOperand(input, HeapObject::kMapOffset), |
6090 factory()->heap_number_map()); | 6114 factory()->heap_number_map()); |
6091 final_branch_condition = equal; | 6115 final_branch_condition = equal; |
6092 | 6116 |
6093 } else if (type_name->Equals(heap()->string_string())) { | 6117 } else if (type_name->Equals(heap()->string_string())) { |
6094 __ JumpIfSmi(input, false_label); | 6118 __ JumpIfSmi(input, false_label, false_distance); |
6095 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 6119 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
6096 __ j(above_equal, false_label); | 6120 __ j(above_equal, false_label, false_distance); |
6097 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6121 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
6098 1 << Map::kIsUndetectable); | 6122 1 << Map::kIsUndetectable); |
6099 final_branch_condition = zero; | 6123 final_branch_condition = zero; |
6100 | 6124 |
6101 } else if (type_name->Equals(heap()->symbol_string())) { | 6125 } else if (type_name->Equals(heap()->symbol_string())) { |
6102 __ JumpIfSmi(input, false_label); | 6126 __ JumpIfSmi(input, false_label, false_distance); |
6103 __ CmpObjectType(input, SYMBOL_TYPE, input); | 6127 __ CmpObjectType(input, SYMBOL_TYPE, input); |
6104 final_branch_condition = equal; | 6128 final_branch_condition = equal; |
6105 | 6129 |
6106 } else if (type_name->Equals(heap()->boolean_string())) { | 6130 } else if (type_name->Equals(heap()->boolean_string())) { |
6107 __ cmp(input, factory()->true_value()); | 6131 __ cmp(input, factory()->true_value()); |
6108 __ j(equal, true_label); | 6132 __ j(equal, true_label, true_distance); |
6109 __ cmp(input, factory()->false_value()); | 6133 __ cmp(input, factory()->false_value()); |
6110 final_branch_condition = equal; | 6134 final_branch_condition = equal; |
6111 | 6135 |
6112 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { | 6136 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |
6113 __ cmp(input, factory()->null_value()); | 6137 __ cmp(input, factory()->null_value()); |
6114 final_branch_condition = equal; | 6138 final_branch_condition = equal; |
6115 | 6139 |
6116 } else if (type_name->Equals(heap()->undefined_string())) { | 6140 } else if (type_name->Equals(heap()->undefined_string())) { |
6117 __ cmp(input, factory()->undefined_value()); | 6141 __ cmp(input, factory()->undefined_value()); |
6118 __ j(equal, true_label); | 6142 __ j(equal, true_label, true_distance); |
6119 __ JumpIfSmi(input, false_label); | 6143 __ JumpIfSmi(input, false_label, false_distance); |
6120 // Check for undetectable objects => true. | 6144 // Check for undetectable objects => true. |
6121 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 6145 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
6122 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6146 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
6123 1 << Map::kIsUndetectable); | 6147 1 << Map::kIsUndetectable); |
6124 final_branch_condition = not_zero; | 6148 final_branch_condition = not_zero; |
6125 | 6149 |
6126 } else if (type_name->Equals(heap()->function_string())) { | 6150 } else if (type_name->Equals(heap()->function_string())) { |
6127 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 6151 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
6128 __ JumpIfSmi(input, false_label); | 6152 __ JumpIfSmi(input, false_label, false_distance); |
6129 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 6153 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |
6130 __ j(equal, true_label); | 6154 __ j(equal, true_label, true_distance); |
6131 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); | 6155 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); |
6132 final_branch_condition = equal; | 6156 final_branch_condition = equal; |
6133 | 6157 |
6134 } else if (type_name->Equals(heap()->object_string())) { | 6158 } else if (type_name->Equals(heap()->object_string())) { |
6135 __ JumpIfSmi(input, false_label); | 6159 __ JumpIfSmi(input, false_label, false_distance); |
6136 if (!FLAG_harmony_typeof) { | 6160 if (!FLAG_harmony_typeof) { |
6137 __ cmp(input, factory()->null_value()); | 6161 __ cmp(input, factory()->null_value()); |
6138 __ j(equal, true_label); | 6162 __ j(equal, true_label, true_distance); |
6139 } | 6163 } |
6140 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 6164 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
6141 __ j(below, false_label); | 6165 __ j(below, false_label, false_distance); |
6142 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 6166 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
6143 __ j(above, false_label); | 6167 __ j(above, false_label, false_distance); |
6144 // Check for undetectable objects => false. | 6168 // Check for undetectable objects => false. |
6145 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6169 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
6146 1 << Map::kIsUndetectable); | 6170 1 << Map::kIsUndetectable); |
6147 final_branch_condition = zero; | 6171 final_branch_condition = zero; |
6148 | 6172 |
6149 } else { | 6173 } else { |
6150 __ jmp(false_label); | 6174 __ jmp(false_label, false_distance); |
6151 } | 6175 } |
6152 return final_branch_condition; | 6176 return final_branch_condition; |
6153 } | 6177 } |
6154 | 6178 |
6155 | 6179 |
6156 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 6180 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
6157 Register temp = ToRegister(instr->temp()); | 6181 Register temp = ToRegister(instr->temp()); |
6158 | 6182 |
6159 EmitIsConstructCall(temp); | 6183 EmitIsConstructCall(temp); |
6160 EmitBranch(instr, equal); | 6184 EmitBranch(instr, equal); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6389 FixedArray::kHeaderSize - kPointerSize)); | 6413 FixedArray::kHeaderSize - kPointerSize)); |
6390 __ bind(&done); | 6414 __ bind(&done); |
6391 } | 6415 } |
6392 | 6416 |
6393 | 6417 |
6394 #undef __ | 6418 #undef __ |
6395 | 6419 |
6396 } } // namespace v8::internal | 6420 } } // namespace v8::internal |
6397 | 6421 |
6398 #endif // V8_TARGET_ARCH_IA32 | 6422 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |