OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 Handle<Object> value = chunk_->LookupLiteral(op); | 315 Handle<Object> value = chunk_->LookupLiteral(op); |
316 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); | 316 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); |
317 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == | 317 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == |
318 value->Number()); | 318 value->Number()); |
319 return static_cast<int32_t>(value->Number()); | 319 return static_cast<int32_t>(value->Number()); |
320 } | 320 } |
321 | 321 |
322 | 322 |
323 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 323 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
324 Handle<Object> literal = chunk_->LookupLiteral(op); | 324 Handle<Object> literal = chunk_->LookupLiteral(op); |
325 Representation r = chunk_->LookupLiteralRepresentation(op); | 325 ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); |
326 ASSERT(r.IsTagged()); | |
327 return literal; | 326 return literal; |
328 } | 327 } |
329 | 328 |
330 | 329 |
331 Operand LCodeGen::ToOperand(LOperand* op) const { | 330 Operand LCodeGen::ToOperand(LOperand* op) const { |
332 // Does not handle registers. In X64 assembler, plain registers are not | 331 // Does not handle registers. In X64 assembler, plain registers are not |
333 // representable as an Operand. | 332 // representable as an Operand. |
334 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); | 333 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); |
335 int index = op->index(); | 334 int index = op->index(); |
336 if (index >= 0) { | 335 if (index >= 0) { |
(...skipping 2831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3168 } else { | 3167 } else { |
3169 __ push(rsi); | 3168 __ push(rsi); |
3170 __ Push(shared_info); | 3169 __ Push(shared_info); |
3171 __ Push(pretenure ? Factory::true_value() : Factory::false_value()); | 3170 __ Push(pretenure ? Factory::true_value() : Factory::false_value()); |
3172 CallRuntime(Runtime::kNewClosure, 3, instr); | 3171 CallRuntime(Runtime::kNewClosure, 3, instr); |
3173 } | 3172 } |
3174 } | 3173 } |
3175 | 3174 |
3176 | 3175 |
3177 void LCodeGen::DoTypeof(LTypeof* instr) { | 3176 void LCodeGen::DoTypeof(LTypeof* instr) { |
3178 Abort("Unimplemented: %s", "DoTypeof"); | 3177 LOperand* input = instr->InputAt(0); |
| 3178 if (input->IsConstantOperand()) { |
| 3179 __ Push(ToHandle(LConstantOperand::cast(input))); |
| 3180 } else if (input->IsRegister()) { |
| 3181 __ push(ToRegister(input)); |
| 3182 } else { |
| 3183 ASSERT(input->IsStackSlot()); |
| 3184 __ push(ToOperand(input)); |
| 3185 } |
| 3186 CallRuntime(Runtime::kTypeof, 1, instr); |
3179 } | 3187 } |
3180 | 3188 |
3181 | 3189 |
3182 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { | 3190 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { |
3183 Abort("Unimplemented: %s", "DoTypeofIs"); | 3191 Register input = ToRegister(instr->InputAt(0)); |
3184 } | |
3185 | |
3186 | |
3187 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { | |
3188 Register result = ToRegister(instr->result()); | 3192 Register result = ToRegister(instr->result()); |
3189 NearLabel true_label; | 3193 Label true_label; |
3190 NearLabel false_label; | 3194 Label false_label; |
3191 NearLabel done; | 3195 NearLabel done; |
3192 | 3196 |
3193 EmitIsConstructCall(result); | 3197 Condition final_branch_condition = EmitTypeofIs(&true_label, |
3194 __ j(equal, &true_label); | 3198 &false_label, |
3195 | 3199 input, |
| 3200 instr->type_literal()); |
| 3201 __ j(final_branch_condition, &true_label); |
| 3202 __ bind(&false_label); |
3196 __ LoadRoot(result, Heap::kFalseValueRootIndex); | 3203 __ LoadRoot(result, Heap::kFalseValueRootIndex); |
3197 __ jmp(&done); | 3204 __ jmp(&done); |
3198 | 3205 |
3199 __ bind(&true_label); | 3206 __ bind(&true_label); |
3200 __ LoadRoot(result, Heap::kTrueValueRootIndex); | 3207 __ LoadRoot(result, Heap::kTrueValueRootIndex); |
3201 | 3208 |
3202 | |
3203 __ bind(&done); | 3209 __ bind(&done); |
3204 } | 3210 } |
3205 | 3211 |
3206 | 3212 |
3207 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | |
3208 Register temp = ToRegister(instr->TempAt(0)); | |
3209 int true_block = chunk_->LookupDestination(instr->true_block_id()); | |
3210 int false_block = chunk_->LookupDestination(instr->false_block_id()); | |
3211 | |
3212 EmitIsConstructCall(temp); | |
3213 EmitBranch(true_block, false_block, equal); | |
3214 } | |
3215 | |
3216 | |
3217 void LCodeGen::EmitIsConstructCall(Register temp) { | |
3218 // Get the frame pointer for the calling frame. | |
3219 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | |
3220 | |
3221 // Skip the arguments adaptor frame if it exists. | |
3222 NearLabel check_frame_marker; | |
3223 __ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset), | |
3224 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | |
3225 __ j(not_equal, &check_frame_marker); | |
3226 __ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset)); | |
3227 | |
3228 // Check the marker in the calling frame. | |
3229 __ bind(&check_frame_marker); | |
3230 __ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset), | |
3231 Smi::FromInt(StackFrame::CONSTRUCT)); | |
3232 } | |
3233 | |
3234 | |
3235 void LCodeGen::EmitPushConstantOperand(LOperand* operand) { | 3213 void LCodeGen::EmitPushConstantOperand(LOperand* operand) { |
3236 ASSERT(operand->IsConstantOperand()); | 3214 ASSERT(operand->IsConstantOperand()); |
3237 LConstantOperand* const_op = LConstantOperand::cast(operand); | 3215 LConstantOperand* const_op = LConstantOperand::cast(operand); |
3238 Handle<Object> literal = chunk_->LookupLiteral(const_op); | 3216 Handle<Object> literal = chunk_->LookupLiteral(const_op); |
3239 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 3217 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
3240 if (r.IsInteger32()) { | 3218 if (r.IsInteger32()) { |
3241 ASSERT(literal->IsNumber()); | 3219 ASSERT(literal->IsNumber()); |
3242 __ push(Immediate(static_cast<int32_t>(literal->Number()))); | 3220 __ push(Immediate(static_cast<int32_t>(literal->Number()))); |
3243 } else if (r.IsDouble()) { | 3221 } else if (r.IsDouble()) { |
3244 Abort("unsupported double immediate"); | 3222 Abort("unsupported double immediate"); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3322 | 3300 |
3323 } else { | 3301 } else { |
3324 final_branch_condition = never; | 3302 final_branch_condition = never; |
3325 __ jmp(false_label); | 3303 __ jmp(false_label); |
3326 } | 3304 } |
3327 | 3305 |
3328 return final_branch_condition; | 3306 return final_branch_condition; |
3329 } | 3307 } |
3330 | 3308 |
3331 | 3309 |
| 3310 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { |
| 3311 Register result = ToRegister(instr->result()); |
| 3312 NearLabel true_label; |
| 3313 NearLabel false_label; |
| 3314 NearLabel done; |
| 3315 |
| 3316 EmitIsConstructCall(result); |
| 3317 __ j(equal, &true_label); |
| 3318 |
| 3319 __ LoadRoot(result, Heap::kFalseValueRootIndex); |
| 3320 __ jmp(&done); |
| 3321 |
| 3322 __ bind(&true_label); |
| 3323 __ LoadRoot(result, Heap::kTrueValueRootIndex); |
| 3324 |
| 3325 |
| 3326 __ bind(&done); |
| 3327 } |
| 3328 |
| 3329 |
| 3330 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 3331 Register temp = ToRegister(instr->TempAt(0)); |
| 3332 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 3333 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 3334 |
| 3335 EmitIsConstructCall(temp); |
| 3336 EmitBranch(true_block, false_block, equal); |
| 3337 } |
| 3338 |
| 3339 |
| 3340 void LCodeGen::EmitIsConstructCall(Register temp) { |
| 3341 // Get the frame pointer for the calling frame. |
| 3342 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 3343 |
| 3344 // Skip the arguments adaptor frame if it exists. |
| 3345 NearLabel check_frame_marker; |
| 3346 __ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset), |
| 3347 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 3348 __ j(not_equal, &check_frame_marker); |
| 3349 __ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset)); |
| 3350 |
| 3351 // Check the marker in the calling frame. |
| 3352 __ bind(&check_frame_marker); |
| 3353 __ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset), |
| 3354 Smi::FromInt(StackFrame::CONSTRUCT)); |
| 3355 } |
| 3356 |
| 3357 |
3332 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { | 3358 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { |
3333 // No code for lazy bailout instruction. Used to capture environment after a | 3359 // No code for lazy bailout instruction. Used to capture environment after a |
3334 // call for populating the safepoint data with deoptimization data. | 3360 // call for populating the safepoint data with deoptimization data. |
3335 } | 3361 } |
3336 | 3362 |
3337 | 3363 |
3338 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { | 3364 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { |
3339 DeoptimizeIf(no_condition, instr->environment()); | 3365 DeoptimizeIf(no_condition, instr->environment()); |
3340 } | 3366 } |
3341 | 3367 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3400 RegisterEnvironmentForDeoptimization(environment); | 3426 RegisterEnvironmentForDeoptimization(environment); |
3401 ASSERT(osr_pc_offset_ == -1); | 3427 ASSERT(osr_pc_offset_ == -1); |
3402 osr_pc_offset_ = masm()->pc_offset(); | 3428 osr_pc_offset_ = masm()->pc_offset(); |
3403 } | 3429 } |
3404 | 3430 |
3405 #undef __ | 3431 #undef __ |
3406 | 3432 |
3407 } } // namespace v8::internal | 3433 } } // namespace v8::internal |
3408 | 3434 |
3409 #endif // V8_TARGET_ARCH_X64 | 3435 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |