Chromium Code Reviews| 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 Representation rep = instr->hydrogen()->value()->representation(); | |
|
Jakob Kummerow
2013/11/08 12:07:05
Thanks to overriding KnownSuccessorBlock and the m
Weiliang
2013/11/08 13:50:26
Done.
| |
| 6072 if (rep.IsSpecialization()) { | |
| 6073 if (instr->hydrogen()->CheckNumberString()) { | |
| 6074 EmitGoto(instr->TrueDestination(chunk_)); | |
| 6075 } else { | |
| 6076 EmitGoto(instr->FalseDestination(chunk_)); | |
| 6077 } | |
| 6078 return; | |
| 6079 } | |
| 6080 | |
| 6071 Register input = ToRegister(instr->value()); | 6081 Register input = ToRegister(instr->value()); |
| 6072 | 6082 Condition final_branch_condition = EmitTypeofIs(instr, input); |
| 6073 Condition final_branch_condition = | |
| 6074 EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), | |
| 6075 input, instr->type_literal()); | |
| 6076 if (final_branch_condition != no_condition) { | 6083 if (final_branch_condition != no_condition) { |
| 6077 EmitBranch(instr, final_branch_condition); | 6084 EmitBranch(instr, final_branch_condition); |
| 6078 } | 6085 } |
| 6079 } | 6086 } |
| 6080 | 6087 |
| 6081 | 6088 |
| 6082 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 6089 Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { |
| 6083 Label* false_label, | 6090 Label* true_label = instr->TrueLabel(chunk_); |
| 6084 Register input, | 6091 Label* false_label = instr->FalseLabel(chunk_); |
| 6085 Handle<String> type_name) { | 6092 Handle<String> type_name = instr->type_literal(); |
| 6093 int left_block = instr->TrueDestination(chunk_); | |
| 6094 int right_block = instr->FalseDestination(chunk_); | |
| 6095 int next_block = GetNextEmittedBlock(); | |
| 6096 | |
| 6097 Label::Distance true_distance = Label::kFar; | |
|
Jakob Kummerow
2013/11/08 12:07:05
Label::Distance true_distance = left_block == next
Weiliang
2013/11/08 13:50:26
Done.
Weiliang
2013/11/08 13:50:26
Done.
| |
| 6098 Label::Distance false_distance = Label::kFar; | |
| 6099 if (left_block == next_block) { | |
| 6100 true_distance = Label::kNear; | |
| 6101 } else if (right_block == next_block) { | |
| 6102 false_distance = Label::kNear; | |
| 6103 } | |
| 6104 | |
| 6086 Condition final_branch_condition = no_condition; | 6105 Condition final_branch_condition = no_condition; |
| 6087 if (type_name->Equals(heap()->number_string())) { | 6106 if (type_name->Equals(heap()->number_string())) { |
| 6088 __ JumpIfSmi(input, true_label); | 6107 __ JumpIfSmi(input, true_label, true_distance); |
| 6089 __ cmp(FieldOperand(input, HeapObject::kMapOffset), | 6108 __ cmp(FieldOperand(input, HeapObject::kMapOffset), |
| 6090 factory()->heap_number_map()); | 6109 factory()->heap_number_map()); |
| 6091 final_branch_condition = equal; | 6110 final_branch_condition = equal; |
| 6092 | 6111 |
| 6093 } else if (type_name->Equals(heap()->string_string())) { | 6112 } else if (type_name->Equals(heap()->string_string())) { |
| 6094 __ JumpIfSmi(input, false_label); | 6113 __ JumpIfSmi(input, false_label, false_distance); |
| 6095 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 6114 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
| 6096 __ j(above_equal, false_label); | 6115 __ j(above_equal, false_label, false_distance); |
| 6097 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6116 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 6098 1 << Map::kIsUndetectable); | 6117 1 << Map::kIsUndetectable); |
| 6099 final_branch_condition = zero; | 6118 final_branch_condition = zero; |
| 6100 | 6119 |
| 6101 } else if (type_name->Equals(heap()->symbol_string())) { | 6120 } else if (type_name->Equals(heap()->symbol_string())) { |
| 6102 __ JumpIfSmi(input, false_label); | 6121 __ JumpIfSmi(input, false_label, false_distance); |
| 6103 __ CmpObjectType(input, SYMBOL_TYPE, input); | 6122 __ CmpObjectType(input, SYMBOL_TYPE, input); |
| 6104 final_branch_condition = equal; | 6123 final_branch_condition = equal; |
| 6105 | 6124 |
| 6106 } else if (type_name->Equals(heap()->boolean_string())) { | 6125 } else if (type_name->Equals(heap()->boolean_string())) { |
| 6107 __ cmp(input, factory()->true_value()); | 6126 __ cmp(input, factory()->true_value()); |
| 6108 __ j(equal, true_label); | 6127 __ j(equal, true_label, true_distance); |
| 6109 __ cmp(input, factory()->false_value()); | 6128 __ cmp(input, factory()->false_value()); |
| 6110 final_branch_condition = equal; | 6129 final_branch_condition = equal; |
| 6111 | 6130 |
| 6112 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { | 6131 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |
| 6113 __ cmp(input, factory()->null_value()); | 6132 __ cmp(input, factory()->null_value()); |
| 6114 final_branch_condition = equal; | 6133 final_branch_condition = equal; |
| 6115 | 6134 |
| 6116 } else if (type_name->Equals(heap()->undefined_string())) { | 6135 } else if (type_name->Equals(heap()->undefined_string())) { |
| 6117 __ cmp(input, factory()->undefined_value()); | 6136 __ cmp(input, factory()->undefined_value()); |
| 6118 __ j(equal, true_label); | 6137 __ j(equal, true_label, true_distance); |
| 6119 __ JumpIfSmi(input, false_label); | 6138 __ JumpIfSmi(input, false_label, false_distance); |
| 6120 // Check for undetectable objects => true. | 6139 // Check for undetectable objects => true. |
| 6121 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 6140 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
| 6122 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6141 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 6123 1 << Map::kIsUndetectable); | 6142 1 << Map::kIsUndetectable); |
| 6124 final_branch_condition = not_zero; | 6143 final_branch_condition = not_zero; |
| 6125 | 6144 |
| 6126 } else if (type_name->Equals(heap()->function_string())) { | 6145 } else if (type_name->Equals(heap()->function_string())) { |
| 6127 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 6146 STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
| 6128 __ JumpIfSmi(input, false_label); | 6147 __ JumpIfSmi(input, false_label, false_distance); |
| 6129 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 6148 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |
| 6130 __ j(equal, true_label); | 6149 __ j(equal, true_label, true_distance); |
| 6131 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); | 6150 __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); |
| 6132 final_branch_condition = equal; | 6151 final_branch_condition = equal; |
| 6133 | 6152 |
| 6134 } else if (type_name->Equals(heap()->object_string())) { | 6153 } else if (type_name->Equals(heap()->object_string())) { |
| 6135 __ JumpIfSmi(input, false_label); | 6154 __ JumpIfSmi(input, false_label, false_distance); |
| 6136 if (!FLAG_harmony_typeof) { | 6155 if (!FLAG_harmony_typeof) { |
| 6137 __ cmp(input, factory()->null_value()); | 6156 __ cmp(input, factory()->null_value()); |
| 6138 __ j(equal, true_label); | 6157 __ j(equal, true_label, true_distance); |
| 6139 } | 6158 } |
| 6140 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); | 6159 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); |
| 6141 __ j(below, false_label); | 6160 __ j(below, false_label, false_distance); |
| 6142 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); | 6161 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 6143 __ j(above, false_label); | 6162 __ j(above, false_label, false_distance); |
| 6144 // Check for undetectable objects => false. | 6163 // Check for undetectable objects => false. |
| 6145 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 6164 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 6146 1 << Map::kIsUndetectable); | 6165 1 << Map::kIsUndetectable); |
| 6147 final_branch_condition = zero; | 6166 final_branch_condition = zero; |
| 6148 | 6167 |
| 6149 } else { | 6168 } else { |
| 6150 __ jmp(false_label); | 6169 __ jmp(false_label, false_distance); |
| 6151 } | 6170 } |
| 6152 return final_branch_condition; | 6171 return final_branch_condition; |
| 6153 } | 6172 } |
| 6154 | 6173 |
| 6155 | 6174 |
| 6156 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 6175 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 6157 Register temp = ToRegister(instr->temp()); | 6176 Register temp = ToRegister(instr->temp()); |
| 6158 | 6177 |
| 6159 EmitIsConstructCall(temp); | 6178 EmitIsConstructCall(temp); |
| 6160 EmitBranch(instr, equal); | 6179 EmitBranch(instr, equal); |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6389 FixedArray::kHeaderSize - kPointerSize)); | 6408 FixedArray::kHeaderSize - kPointerSize)); |
| 6390 __ bind(&done); | 6409 __ bind(&done); |
| 6391 } | 6410 } |
| 6392 | 6411 |
| 6393 | 6412 |
| 6394 #undef __ | 6413 #undef __ |
| 6395 | 6414 |
| 6396 } } // namespace v8::internal | 6415 } } // namespace v8::internal |
| 6397 | 6416 |
| 6398 #endif // V8_TARGET_ARCH_IA32 | 6417 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |