| 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 |