OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 previous_(owner->state()) { | 131 previous_(owner->state()) { |
132 owner_->set_state(this); | 132 owner_->set_state(this); |
133 } | 133 } |
134 | 134 |
135 | 135 |
136 CodeGenState::~CodeGenState() { | 136 CodeGenState::~CodeGenState() { |
137 ASSERT(owner_->state() == this); | 137 ASSERT(owner_->state() == this); |
138 owner_->set_state(previous_); | 138 owner_->set_state(previous_); |
139 } | 139 } |
140 | 140 |
141 | |
142 // ------------------------------------------------------------------------- | 141 // ------------------------------------------------------------------------- |
143 // CodeGenerator implementation. | 142 // CodeGenerator implementation. |
144 | 143 |
145 CodeGenerator::CodeGenerator(MacroAssembler* masm) | 144 CodeGenerator::CodeGenerator(MacroAssembler* masm) |
146 : deferred_(8), | 145 : deferred_(8), |
147 masm_(masm), | 146 masm_(masm), |
148 info_(NULL), | 147 info_(NULL), |
149 frame_(NULL), | 148 frame_(NULL), |
150 allocator_(NULL), | 149 allocator_(NULL), |
151 state_(NULL), | 150 state_(NULL), |
(...skipping 5150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5302 __ push(Immediate(Smi::FromInt(node_->literal_index()))); | 5301 __ push(Immediate(Smi::FromInt(node_->literal_index()))); |
5303 // RegExp pattern (2). | 5302 // RegExp pattern (2). |
5304 __ push(Immediate(node_->pattern())); | 5303 __ push(Immediate(node_->pattern())); |
5305 // RegExp flags (3). | 5304 // RegExp flags (3). |
5306 __ push(Immediate(node_->flags())); | 5305 __ push(Immediate(node_->flags())); |
5307 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 5306 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
5308 if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax); | 5307 if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax); |
5309 } | 5308 } |
5310 | 5309 |
5311 | 5310 |
| 5311 class DeferredAllocateInNewSpace: public DeferredCode { |
| 5312 public: |
| 5313 DeferredAllocateInNewSpace(int size, Register target) |
| 5314 : size_(size), target_(target) { |
| 5315 ASSERT(size >= kPointerSize && size <= Heap::MaxObjectSizeInNewSpace()); |
| 5316 set_comment("[ DeferredAllocateInNewSpace"); |
| 5317 } |
| 5318 void Generate(); |
| 5319 |
| 5320 private: |
| 5321 int size_; |
| 5322 Register target_; |
| 5323 }; |
| 5324 |
| 5325 |
| 5326 void DeferredAllocateInNewSpace::Generate() { |
| 5327 __ push(Immediate(Smi::FromInt(size_))); |
| 5328 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 5329 if (!target_.is(eax)) { |
| 5330 __ mov(target_, eax); |
| 5331 } |
| 5332 } |
| 5333 |
| 5334 |
5312 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { | 5335 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { |
5313 ASSERT(!in_safe_int32_mode()); | 5336 ASSERT(!in_safe_int32_mode()); |
5314 Comment cmnt(masm_, "[ RegExp Literal"); | 5337 Comment cmnt(masm_, "[ RegExp Literal"); |
5315 | 5338 |
5316 // Retrieve the literals array and check the allocated entry. Begin | 5339 // Retrieve the literals array and check the allocated entry. Begin |
5317 // with a writable copy of the function of this activation in a | 5340 // with a writable copy of the function of this activation in a |
5318 // register. | 5341 // register. |
5319 frame_->PushFunction(); | 5342 frame_->PushFunction(); |
5320 Result literals = frame_->Pop(); | 5343 Result literals = frame_->Pop(); |
5321 literals.ToRegister(); | 5344 literals.ToRegister(); |
(...skipping 10 matching lines...) Expand all Loading... |
5332 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 5355 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; |
5333 __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); | 5356 __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); |
5334 | 5357 |
5335 // Check whether we need to materialize the RegExp object. If so, | 5358 // Check whether we need to materialize the RegExp object. If so, |
5336 // jump to the deferred code passing the literals array. | 5359 // jump to the deferred code passing the literals array. |
5337 DeferredRegExpLiteral* deferred = | 5360 DeferredRegExpLiteral* deferred = |
5338 new DeferredRegExpLiteral(boilerplate.reg(), literals.reg(), node); | 5361 new DeferredRegExpLiteral(boilerplate.reg(), literals.reg(), node); |
5339 __ cmp(boilerplate.reg(), Factory::undefined_value()); | 5362 __ cmp(boilerplate.reg(), Factory::undefined_value()); |
5340 deferred->Branch(equal); | 5363 deferred->Branch(equal); |
5341 deferred->BindExit(); | 5364 deferred->BindExit(); |
5342 literals.Unuse(); | |
5343 | 5365 |
5344 // Push the boilerplate object. | 5366 // Register of boilerplate contains RegExp object. |
| 5367 |
| 5368 Result tmp = allocator()->Allocate(); |
| 5369 ASSERT(tmp.is_valid()); |
| 5370 |
| 5371 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
| 5372 |
| 5373 DeferredAllocateInNewSpace* allocate_fallback = |
| 5374 new DeferredAllocateInNewSpace(size, literals.reg()); |
5345 frame_->Push(&boilerplate); | 5375 frame_->Push(&boilerplate); |
| 5376 frame_->SpillTop(); |
| 5377 __ AllocateInNewSpace(size, |
| 5378 literals.reg(), |
| 5379 tmp.reg(), |
| 5380 no_reg, |
| 5381 allocate_fallback->entry_label(), |
| 5382 TAG_OBJECT); |
| 5383 allocate_fallback->BindExit(); |
| 5384 boilerplate = frame_->Pop(); |
| 5385 // Copy from boilerplate to clone and return clone. |
| 5386 |
| 5387 for (int i = 0; i < size; i += kPointerSize) { |
| 5388 __ mov(tmp.reg(), FieldOperand(boilerplate.reg(), i)); |
| 5389 __ mov(FieldOperand(literals.reg(), i), tmp.reg()); |
| 5390 } |
| 5391 frame_->Push(&literals); |
5346 } | 5392 } |
5347 | 5393 |
5348 | 5394 |
5349 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | 5395 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { |
5350 ASSERT(!in_safe_int32_mode()); | 5396 ASSERT(!in_safe_int32_mode()); |
5351 Comment cmnt(masm_, "[ ObjectLiteral"); | 5397 Comment cmnt(masm_, "[ ObjectLiteral"); |
5352 | 5398 |
5353 // Load a writable copy of the function of this activation in a | 5399 // Load a writable copy of the function of this activation in a |
5354 // register. | 5400 // register. |
5355 frame_->PushFunction(); | 5401 frame_->PushFunction(); |
(...skipping 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7518 SetFrame(clone, &empty_regs); | 7564 SetFrame(clone, &empty_regs); |
7519 __ bind(&runtime); | 7565 __ bind(&runtime); |
7520 result = frame()->CallRuntime(Runtime::kMath_sqrt, 1); | 7566 result = frame()->CallRuntime(Runtime::kMath_sqrt, 1); |
7521 | 7567 |
7522 end.Bind(&result); | 7568 end.Bind(&result); |
7523 frame()->Push(&result); | 7569 frame()->Push(&result); |
7524 } | 7570 } |
7525 } | 7571 } |
7526 | 7572 |
7527 | 7573 |
| 7574 void CodeGenerator::GenerateIsRegExpEquivalent(ZoneList<Expression*>* args) { |
| 7575 ASSERT_EQ(2, args->length()); |
| 7576 Load(args->at(0)); |
| 7577 Load(args->at(1)); |
| 7578 Result right_res = frame_->Pop(); |
| 7579 Result left_res = frame_->Pop(); |
| 7580 right_res.ToRegister(); |
| 7581 left_res.ToRegister(); |
| 7582 Result tmp_res = allocator()->Allocate(); |
| 7583 ASSERT(tmp_res.is_valid()); |
| 7584 Register right = right_res.reg(); |
| 7585 Register left = left_res.reg(); |
| 7586 Register tmp = tmp_res.reg(); |
| 7587 right_res.Unuse(); |
| 7588 left_res.Unuse(); |
| 7589 tmp_res.Unuse(); |
| 7590 __ cmp(left, Operand(right)); |
| 7591 destination()->true_target()->Branch(equal); |
| 7592 // Fail if either is a non-HeapObject. |
| 7593 __ mov(tmp, left); |
| 7594 __ and_(Operand(tmp), right); |
| 7595 __ test(Operand(tmp), Immediate(kSmiTagMask)); |
| 7596 destination()->false_target()->Branch(equal); |
| 7597 __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset)); |
| 7598 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), |
| 7599 static_cast<int8_t>(JS_REGEXP_TYPE)); |
| 7600 destination()->false_target()->Branch(not_equal); |
| 7601 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset)); |
| 7602 destination()->false_target()->Branch(not_equal); |
| 7603 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); |
| 7604 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); |
| 7605 destination()->Split(equal); |
| 7606 } |
| 7607 |
| 7608 |
7528 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { | 7609 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { |
7529 ASSERT(!in_safe_int32_mode()); | 7610 ASSERT(!in_safe_int32_mode()); |
7530 if (CheckForInlineRuntimeCall(node)) { | 7611 if (CheckForInlineRuntimeCall(node)) { |
7531 return; | 7612 return; |
7532 } | 7613 } |
7533 | 7614 |
7534 ZoneList<Expression*>* args = node->arguments(); | 7615 ZoneList<Expression*>* args = node->arguments(); |
7535 Comment cmnt(masm_, "[ CallRuntime"); | 7616 Comment cmnt(masm_, "[ CallRuntime"); |
7536 Runtime::Function* function = node->function(); | 7617 Runtime::Function* function = node->function(); |
7537 | 7618 |
(...skipping 6421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13959 masm.GetCode(&desc); | 14040 masm.GetCode(&desc); |
13960 // Call the function from C++. | 14041 // Call the function from C++. |
13961 return FUNCTION_CAST<MemCopyFunction>(buffer); | 14042 return FUNCTION_CAST<MemCopyFunction>(buffer); |
13962 } | 14043 } |
13963 | 14044 |
13964 #undef __ | 14045 #undef __ |
13965 | 14046 |
13966 } } // namespace v8::internal | 14047 } } // namespace v8::internal |
13967 | 14048 |
13968 #endif // V8_TARGET_ARCH_IA32 | 14049 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |