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