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 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 // Notice: We must not have a "test rax, ..." instruction after the | 1192 // Notice: We must not have a "test rax, ..." instruction after the |
1193 // call. It is treated specially by the LoadIC code. | 1193 // call. It is treated specially by the LoadIC code. |
1194 __ nop(); | 1194 __ nop(); |
1195 Apply(context, rax); | 1195 Apply(context, rax); |
1196 } | 1196 } |
1197 } | 1197 } |
1198 | 1198 |
1199 | 1199 |
1200 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1200 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1201 Comment cmnt(masm_, "[ RegExpLiteral"); | 1201 Comment cmnt(masm_, "[ RegExpLiteral"); |
1202 Label done; | 1202 Label materialized; |
1203 // Registers will be used as follows: | 1203 // Registers will be used as follows: |
1204 // rdi = JS function. | 1204 // rdi = JS function. |
1205 // rbx = literals array. | 1205 // rcx = literals array. |
1206 // rax = regexp literal. | 1206 // rbx = regexp literal. |
| 1207 // rax = regexp literal clone. |
1207 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1208 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1208 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); | 1209 __ movq(rcx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); |
1209 int literal_offset = | 1210 int literal_offset = |
1210 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; | 1211 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
1211 __ movq(rax, FieldOperand(rbx, literal_offset)); | 1212 __ movq(rbx, FieldOperand(rcx, literal_offset)); |
1212 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 1213 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); |
1213 __ j(not_equal, &done); | 1214 __ j(not_equal, &materialized); |
| 1215 |
1214 // Create regexp literal using runtime function | 1216 // Create regexp literal using runtime function |
1215 // Result will be in rax. | 1217 // Result will be in rax. |
1216 __ push(rbx); | 1218 __ push(rcx); |
1217 __ Push(Smi::FromInt(expr->literal_index())); | 1219 __ Push(Smi::FromInt(expr->literal_index())); |
1218 __ Push(expr->pattern()); | 1220 __ Push(expr->pattern()); |
1219 __ Push(expr->flags()); | 1221 __ Push(expr->flags()); |
1220 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 1222 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
1221 __ bind(&done); | 1223 __ movq(rbx, rax); |
| 1224 |
| 1225 __ bind(&materialized); |
| 1226 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
| 1227 Label allocated, runtime_allocate; |
| 1228 __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); |
| 1229 __ jmp(&allocated); |
| 1230 |
| 1231 __ bind(&runtime_allocate); |
| 1232 __ push(rbx); |
| 1233 __ Push(Smi::FromInt(size)); |
| 1234 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 1235 __ pop(rbx); |
| 1236 |
| 1237 __ bind(&allocated); |
| 1238 // Copy the content into the newly allocated memory. |
| 1239 // (Unroll copy loop once for better throughput). |
| 1240 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { |
| 1241 __ movq(rdx, FieldOperand(rbx, i)); |
| 1242 __ movq(rcx, FieldOperand(rbx, i + kPointerSize)); |
| 1243 __ movq(FieldOperand(rax, i), rdx); |
| 1244 __ movq(FieldOperand(rax, i + kPointerSize), rcx); |
| 1245 } |
| 1246 if ((size % (2 * kPointerSize)) != 0) { |
| 1247 __ movq(rdx, FieldOperand(rbx, size - kPointerSize)); |
| 1248 __ movq(FieldOperand(rax, size - kPointerSize), rdx); |
| 1249 } |
1222 Apply(context_, rax); | 1250 Apply(context_, rax); |
1223 } | 1251 } |
1224 | 1252 |
1225 | 1253 |
1226 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1254 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
1227 Comment cmnt(masm_, "[ ObjectLiteral"); | 1255 Comment cmnt(masm_, "[ ObjectLiteral"); |
1228 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1256 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1229 __ push(FieldOperand(rdi, JSFunction::kLiteralsOffset)); | 1257 __ push(FieldOperand(rdi, JSFunction::kLiteralsOffset)); |
1230 __ Push(Smi::FromInt(expr->literal_index())); | 1258 __ Push(Smi::FromInt(expr->literal_index())); |
1231 __ Push(expr->constant_properties()); | 1259 __ Push(expr->constant_properties()); |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2637 // Call runtime to perform the lookup. | 2665 // Call runtime to perform the lookup. |
2638 __ push(cache); | 2666 __ push(cache); |
2639 __ push(key); | 2667 __ push(key); |
2640 __ CallRuntime(Runtime::kGetFromCache, 2); | 2668 __ CallRuntime(Runtime::kGetFromCache, 2); |
2641 | 2669 |
2642 __ bind(&done); | 2670 __ bind(&done); |
2643 Apply(context_, rax); | 2671 Apply(context_, rax); |
2644 } | 2672 } |
2645 | 2673 |
2646 | 2674 |
| 2675 void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) { |
| 2676 ASSERT_EQ(2, args->length()); |
| 2677 |
| 2678 Register right = rax; |
| 2679 Register left = rbx; |
| 2680 Register tmp = rcx; |
| 2681 |
| 2682 VisitForValue(args->at(0), kStack); |
| 2683 VisitForValue(args->at(1), kAccumulator); |
| 2684 __ pop(left); |
| 2685 |
| 2686 Label done, fail, ok; |
| 2687 __ cmpq(left, right); |
| 2688 __ j(equal, &ok); |
| 2689 // Fail if either is a non-HeapObject. |
| 2690 Condition either_smi = masm()->CheckEitherSmi(left, right, tmp); |
| 2691 __ j(either_smi, &fail); |
| 2692 __ j(zero, &fail); |
| 2693 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); |
| 2694 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), |
| 2695 Immediate(JS_REGEXP_TYPE)); |
| 2696 __ j(not_equal, &fail); |
| 2697 __ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset)); |
| 2698 __ j(not_equal, &fail); |
| 2699 __ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset)); |
| 2700 __ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset)); |
| 2701 __ j(equal, &ok); |
| 2702 __ bind(&fail); |
| 2703 __ Move(rax, Factory::false_value()); |
| 2704 __ jmp(&done); |
| 2705 __ bind(&ok); |
| 2706 __ Move(rax, Factory::true_value()); |
| 2707 __ bind(&done); |
| 2708 |
| 2709 Apply(context_, rax); |
| 2710 } |
| 2711 |
| 2712 |
2647 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 2713 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
2648 Handle<String> name = expr->name(); | 2714 Handle<String> name = expr->name(); |
2649 if (name->length() > 0 && name->Get(0) == '_') { | 2715 if (name->length() > 0 && name->Get(0) == '_') { |
2650 Comment cmnt(masm_, "[ InlineRuntimeCall"); | 2716 Comment cmnt(masm_, "[ InlineRuntimeCall"); |
2651 EmitInlineRuntimeCall(expr); | 2717 EmitInlineRuntimeCall(expr); |
2652 return; | 2718 return; |
2653 } | 2719 } |
2654 | 2720 |
2655 Comment cmnt(masm_, "[ CallRuntime"); | 2721 Comment cmnt(masm_, "[ CallRuntime"); |
2656 ZoneList<Expression*>* args = expr->arguments(); | 2722 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3261 __ ret(0); | 3327 __ ret(0); |
3262 } | 3328 } |
3263 | 3329 |
3264 | 3330 |
3265 #undef __ | 3331 #undef __ |
3266 | 3332 |
3267 | 3333 |
3268 } } // namespace v8::internal | 3334 } } // namespace v8::internal |
3269 | 3335 |
3270 #endif // V8_TARGET_ARCH_X64 | 3336 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |