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