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 5695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6025 } | 6025 } |
6026 } | 6026 } |
6027 | 6027 |
6028 | 6028 |
6029 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 6029 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
6030 Register result = ToRegister(instr->result()); | 6030 Register result = ToRegister(instr->result()); |
6031 | 6031 |
6032 // TODO(3095996): Get rid of this. For now, we need to make the | 6032 // TODO(3095996): Get rid of this. For now, we need to make the |
6033 // result register contain a valid pointer because it is already | 6033 // result register contain a valid pointer because it is already |
6034 // contained in the register pointer map. | 6034 // contained in the register pointer map. |
6035 __ mov(result, Immediate(Smi::FromInt(0))); | 6035 __ Set(result, Immediate(Smi::FromInt(0))); |
6036 | 6036 |
6037 PushSafepointRegistersScope scope(this); | 6037 PushSafepointRegistersScope scope(this); |
6038 if (instr->size()->IsRegister()) { | 6038 if (instr->size()->IsRegister()) { |
6039 Register size = ToRegister(instr->size()); | 6039 Register size = ToRegister(instr->size()); |
6040 ASSERT(!size.is(result)); | 6040 ASSERT(!size.is(result)); |
6041 __ SmiTag(ToRegister(instr->size())); | 6041 __ SmiTag(ToRegister(instr->size())); |
6042 __ push(size); | 6042 __ push(size); |
6043 } else { | 6043 } else { |
6044 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 6044 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
6045 __ push(Immediate(Smi::FromInt(size))); | 6045 __ push(Immediate(Smi::FromInt(size))); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6144 void LCodeGen::DoTypeof(LTypeof* instr) { | 6144 void LCodeGen::DoTypeof(LTypeof* instr) { |
6145 ASSERT(ToRegister(instr->context()).is(esi)); | 6145 ASSERT(ToRegister(instr->context()).is(esi)); |
6146 LOperand* input = instr->value(); | 6146 LOperand* input = instr->value(); |
6147 EmitPushTaggedOperand(input); | 6147 EmitPushTaggedOperand(input); |
6148 CallRuntime(Runtime::kTypeof, 1, instr); | 6148 CallRuntime(Runtime::kTypeof, 1, instr); |
6149 } | 6149 } |
6150 | 6150 |
6151 | 6151 |
6152 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 6152 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
6153 Register input = ToRegister(instr->value()); | 6153 Register input = ToRegister(instr->value()); |
6154 | 6154 Condition final_branch_condition = EmitTypeofIs(instr, input); |
6155 Condition final_branch_condition = | |
6156 EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), | |
6157 input, instr->type_literal()); | |
6158 if (final_branch_condition != no_condition) { | 6155 if (final_branch_condition != no_condition) { |
6159 EmitBranch(instr, final_branch_condition); | 6156 EmitBranch(instr, final_branch_condition); |
6160 } | 6157 } |
6161 } | 6158 } |
6162 | 6159 |
6163 | 6160 |
6164 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 6161 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { |
6165 Label* false_label, | 6162 Label* true_label = instr->TrueLabel(chunk_); |
6166 Register input, | 6163 Label* false_label = instr->FalseLabel(chunk_); |
6167 Handle<String> type_name) { | 6164 Handle<String> type_name = instr->type_literal(); |
| 6165 int left_block = instr->TrueDestination(chunk_); |
| 6166 int right_block = instr->FalseDestination(chunk_); |
| 6167 int next_block = GetNextEmittedBlock(); |
| 6168 |
| 6169 Label::Distance true_distance = left_block == next_block ? Label::kNear |
| 6170 : Label::kFar; |
| 6171 Label::Distance false_distance = right_block == next_block ? Label::kNear |
| 6172 : Label::kFar; |
6168 Condition final_branch_condition = no_condition; | 6173 Condition final_branch_condition = no_condition; |
6169 if (type_name->Equals(heap()->number_string())) { | 6174 if (type_name->Equals(heap()->number_string())) { |
6170 __ JumpIfSmi(input, true_label); | 6175 __ JumpIfSmi(input, true_label, true_distance); |
6171 __ cmp(FieldOperand(input, HeapObject::kMapOffset), | 6176 __ cmp(FieldOperand(input, HeapObject::kMapOffset), |
6172 factory()->heap_number_map()); | 6177 factory()->heap_number_map()); |
6173 final_branch_condition = equal; | 6178 final_branch_condition = equal; |
6174 | 6179 |
6175 } else if (type_name->Equals(heap()->string_string())) { | 6180 } else if (type_name->Equals(heap()->string_string())) { |
6176 __ JumpIfSmi(input, false_label); | 6181 __ JumpIfSmi(input, false_label, false_distance); |
6177 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 6182 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
6178 __ j(above_equal, false_label); | 6183 __ j(above_equal, false_label, false_distance); |
6179 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6184 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
6180 1 << Map::kIsUndetectable); | 6185 1 << Map::kIsUndetectable); |
6181 final_branch_condition = zero; | 6186 final_branch_condition = zero; |
6182 | 6187 |
6183 } else if (type_name->Equals(heap()->symbol_string())) { | 6188 } else if (type_name->Equals(heap()->symbol_string())) { |
6184 __ JumpIfSmi(input, false_label); | 6189 __ JumpIfSmi(input, false_label, false_distance); |
6185 __ CmpObjectType(input, SYMBOL_TYPE, input); | 6190 __ CmpObjectType(input, SYMBOL_TYPE, input); |
6186 final_branch_condition = equal; | 6191 final_branch_condition = equal; |
6187 | 6192 |
6188 } else if (type_name->Equals(heap()->boolean_string())) { | 6193 } else if (type_name->Equals(heap()->boolean_string())) { |
6189 __ cmp(input, factory()->true_value()); | 6194 __ cmp(input, factory()->true_value()); |
6190 __ j(equal, true_label); | 6195 __ j(equal, true_label, true_distance); |
6191 __ cmp(input, factory()->false_value()); | 6196 __ cmp(input, factory()->false_value()); |
6192 final_branch_condition = equal; | 6197 final_branch_condition = equal; |
6193 | 6198 |
6194 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { | 6199 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |
6195 __ cmp(input, factory()->null_value()); | 6200 __ cmp(input, factory()->null_value()); |
6196 final_branch_condition = equal; | 6201 final_branch_condition = equal; |
6197 | 6202 |
6198 } else if (type_name->Equals(heap()->undefined_string())) { | 6203 } else if (type_name->Equals(heap()->undefined_string())) { |
6199 __ cmp(input, factory()->undefined_value()); | 6204 __ cmp(input, factory()->undefined_value()); |
6200 __ j(equal, true_label); | 6205 __ j(equal, true_label, true_distance); |
6201 __ JumpIfSmi(input, false_label); | 6206 __ JumpIfSmi(input, false_label, false_distance); |
6202 // Check for undetectable objects => true. | 6207 // Check for undetectable objects => true. |
6203 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 6208 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
6204 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6209 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
6205 1 << Map::kIsUndetectable); | 6210 1 << Map::kIsUndetectable); |
6206 final_branch_condition = not_zero; | 6211 final_branch_condition = not_zero; |
6207 | 6212 |
6208 } else if (type_name->Equals(heap()->function_string())) { | 6213 } else if (type_name->Equals(heap()->function_string())) { |
6209 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 6214 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
6210 __ JumpIfSmi(input, false_label); | 6215 __ JumpIfSmi(input, false_label, false_distance); |
6211 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 6216 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |
6212 __ j(equal, true_label); | 6217 __ j(equal, true_label, true_distance); |
6213 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); | 6218 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); |
6214 final_branch_condition = equal; | 6219 final_branch_condition = equal; |
6215 | 6220 |
6216 } else if (type_name->Equals(heap()->object_string())) { | 6221 } else if (type_name->Equals(heap()->object_string())) { |
6217 __ JumpIfSmi(input, false_label); | 6222 __ JumpIfSmi(input, false_label, false_distance); |
6218 if (!FLAG_harmony_typeof) { | 6223 if (!FLAG_harmony_typeof) { |
6219 __ cmp(input, factory()->null_value()); | 6224 __ cmp(input, factory()->null_value()); |
6220 __ j(equal, true_label); | 6225 __ j(equal, true_label, true_distance); |
6221 } | 6226 } |
6222 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 6227 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
6223 __ j(below, false_label); | 6228 __ j(below, false_label, false_distance); |
6224 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 6229 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
6225 __ j(above, false_label); | 6230 __ j(above, false_label, false_distance); |
6226 // Check for undetectable objects => false. | 6231 // Check for undetectable objects => false. |
6227 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6232 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
6228 1 << Map::kIsUndetectable); | 6233 1 << Map::kIsUndetectable); |
6229 final_branch_condition = zero; | 6234 final_branch_condition = zero; |
6230 | 6235 |
6231 } else { | 6236 } else { |
6232 __ jmp(false_label); | 6237 __ jmp(false_label, false_distance); |
6233 } | 6238 } |
6234 return final_branch_condition; | 6239 return final_branch_condition; |
6235 } | 6240 } |
6236 | 6241 |
6237 | 6242 |
6238 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 6243 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
6239 Register temp = ToRegister(instr->temp()); | 6244 Register temp = ToRegister(instr->temp()); |
6240 | 6245 |
6241 EmitIsConstructCall(temp); | 6246 EmitIsConstructCall(temp); |
6242 EmitBranch(instr, equal); | 6247 EmitBranch(instr, equal); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6477 FixedArray::kHeaderSize - kPointerSize)); | 6482 FixedArray::kHeaderSize - kPointerSize)); |
6478 __ bind(&done); | 6483 __ bind(&done); |
6479 } | 6484 } |
6480 | 6485 |
6481 | 6486 |
6482 #undef __ | 6487 #undef __ |
6483 | 6488 |
6484 } } // namespace v8::internal | 6489 } } // namespace v8::internal |
6485 | 6490 |
6486 #endif // V8_TARGET_ARCH_IA32 | 6491 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |