Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(570)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 3034060: Create a new RegExp object for every evaluation of a RegExp literal. (Closed)
Patch Set: Addressed review comments. Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698