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

Side by Side Diff: test/cctest/interpreter/test-bytecode-generator.cc

Issue 1471913004: Revert of [Interpreter] Add CreateClosure to BytecodeGraphBuilder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // TODO(rmcilroy): Remove this define after this flag is turned on globally 5 // TODO(rmcilroy): Remove this define after this flag is turned on globally
6 #define V8_IMMINENT_DEPRECATION_WARNINGS 6 #define V8_IMMINENT_DEPRECATION_WARNINGS
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 2647 matching lines...) Expand 10 before | Expand all | Expand 10 after
2658 B(LdaFalse), // 2658 B(LdaFalse), //
2659 B(Return) 2659 B(Return)
2660 }, 2660 },
2661 0}, 2661 0},
2662 {"'use strict';" 2662 {"'use strict';"
2663 "var a = {1:10};" 2663 "var a = {1:10};"
2664 "(function f1() {return a;});" 2664 "(function f1() {return a;});"
2665 "return delete a[1];", 2665 "return delete a[1];",
2666 2 * kPointerSize, 2666 2 * kPointerSize,
2667 1, 2667 1,
2668 28, 2668 29,
2669 { 2669 {
2670 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 2670 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
2671 R(closure), U8(1), // 2671 R(closure), U8(1), //
2672 B(PushContext), R(0), // 2672 B(PushContext), R(0), //
2673 B(LdaConstant), U8(0), // 2673 B(LdaConstant), U8(0), //
2674 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // 2674 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), //
2675 B(StaContextSlot), R(0), U8(first_context_slot), // 2675 B(StaContextSlot), R(0), U8(first_context_slot), //
2676 B(CreateClosure), U8(1), U8(0), // 2676 B(LdaConstant), U8(1), //
2677 B(CreateClosure), U8(0), //
2677 B(LdaContextSlot), R(0), U8(first_context_slot), // 2678 B(LdaContextSlot), R(0), U8(first_context_slot), //
2678 B(Star), R(1), // 2679 B(Star), R(1), //
2679 B(LdaSmi8), U8(1), // 2680 B(LdaSmi8), U8(1), //
2680 B(DeletePropertyStrict), R(1), // 2681 B(DeletePropertyStrict), R(1), //
2681 B(Return) 2682 B(Return)
2682 }, 2683 },
2683 2, 2684 2,
2684 {InstanceType::FIXED_ARRAY_TYPE, 2685 {InstanceType::FIXED_ARRAY_TYPE,
2685 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 2686 InstanceType::SHARED_FUNCTION_INFO_TYPE}},
2686 {"return delete 'test';", 2687 {"return delete 'test';",
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2787 FeedbackVectorSpec feedback_spec(&zone); 2788 FeedbackVectorSpec feedback_spec(&zone);
2788 FeedbackVectorSlot slot = feedback_spec.AddCallICSlot(); 2789 FeedbackVectorSlot slot = feedback_spec.AddCallICSlot();
2789 2790
2790 Handle<i::TypeFeedbackVector> vector = 2791 Handle<i::TypeFeedbackVector> vector =
2791 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 2792 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
2792 2793
2793 ExpectedSnippet<InstanceType> snippets[] = { 2794 ExpectedSnippet<InstanceType> snippets[] = {
2794 {"return function(){ }", 2795 {"return function(){ }",
2795 0, 2796 0,
2796 1, 2797 1,
2797 4, 2798 5,
2798 { 2799 {
2799 B(CreateClosure), U8(0), U8(0), // 2800 B(LdaConstant), U8(0), //
2800 B(Return) // 2801 B(CreateClosure), U8(0), //
2802 B(Return) //
2801 }, 2803 },
2802 1, 2804 1,
2803 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 2805 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
2804 {"return (function(){ })()", 2806 {"return (function(){ })()",
2805 2 * kPointerSize, 2807 2 * kPointerSize,
2806 1, 2808 1,
2807 14, 2809 15,
2808 { 2810 {
2809 B(LdaUndefined), // 2811 B(LdaUndefined), //
2810 B(Star), R(1), // 2812 B(Star), R(1), //
2811 B(CreateClosure), U8(0), U8(0), // 2813 B(LdaConstant), U8(0), //
2814 B(CreateClosure), U8(0), //
2812 B(Star), R(0), // 2815 B(Star), R(0), //
2813 B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot)), // 2816 B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot)), //
2814 B(Return) // 2817 B(Return) //
2815 }, 2818 },
2816 1, 2819 1,
2817 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 2820 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
2818 {"return (function(x){ return x; })(1)", 2821 {"return (function(x){ return x; })(1)",
2819 3 * kPointerSize, 2822 3 * kPointerSize,
2820 1, 2823 1,
2821 18, 2824 19,
2822 { 2825 {
2823 B(LdaUndefined), // 2826 B(LdaUndefined), //
2824 B(Star), R(1), // 2827 B(Star), R(1), //
2825 B(CreateClosure), U8(0), U8(0), // 2828 B(LdaConstant), U8(0), //
2829 B(CreateClosure), U8(0), //
2826 B(Star), R(0), // 2830 B(Star), R(0), //
2827 B(LdaSmi8), U8(1), // 2831 B(LdaSmi8), U8(1), //
2828 B(Star), R(2), // 2832 B(Star), R(2), //
2829 B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot)), // 2833 B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot)), //
2830 B(Return) // 2834 B(Return) //
2831 }, 2835 },
2832 1, 2836 1,
2833 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 2837 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
2834 }; 2838 };
2835 2839
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
3093 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // 3097 B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), //
3094 B(Ldar), R(1), // 3098 B(Ldar), R(1), //
3095 B(Return), // 3099 B(Return), //
3096 }, 3100 },
3097 2, 3101 2,
3098 {InstanceType::FIXED_ARRAY_TYPE, 3102 {InstanceType::FIXED_ARRAY_TYPE,
3099 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, 3103 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
3100 {"return { func: function() { } };", 3104 {"return { func: function() { } };",
3101 1 * kPointerSize, 3105 1 * kPointerSize,
3102 1, 3106 1,
3103 17, 3107 18,
3104 { 3108 {
3105 B(LdaConstant), U8(0), // 3109 B(LdaConstant), U8(0), //
3106 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // 3110 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), //
3107 B(Star), R(0), // 3111 B(Star), R(0), //
3108 B(CreateClosure), U8(2), U8(0), // 3112 B(LdaConstant), U8(2), //
3113 B(CreateClosure), U8(0), //
3109 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // 3114 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), //
3110 B(Ldar), R(0), // 3115 B(Ldar), R(0), //
3111 B(Return), // 3116 B(Return), //
3112 }, 3117 },
3113 3, 3118 3,
3114 {InstanceType::FIXED_ARRAY_TYPE, 3119 {InstanceType::FIXED_ARRAY_TYPE,
3115 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 3120 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
3116 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3121 InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3117 {"return { func(a) { return a; } };", 3122 {"return { func(a) { return a; } };",
3118 1 * kPointerSize, 3123 1 * kPointerSize,
3119 1, 3124 1,
3120 17, 3125 18,
3121 { 3126 {
3122 B(LdaConstant), U8(0), // 3127 B(LdaConstant), U8(0), //
3123 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // 3128 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), //
3124 B(Star), R(0), // 3129 B(Star), R(0), //
3125 B(CreateClosure), U8(2), U8(0), // 3130 B(LdaConstant), U8(2), //
3131 B(CreateClosure), U8(0), //
3126 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // 3132 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), //
3127 B(Ldar), R(0), // 3133 B(Ldar), R(0), //
3128 B(Return), // 3134 B(Return), //
3129 }, 3135 },
3130 3, 3136 3,
3131 {InstanceType::FIXED_ARRAY_TYPE, 3137 {InstanceType::FIXED_ARRAY_TYPE,
3132 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 3138 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
3133 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3139 InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3134 {"return { get a() { return 2; } };", 3140 {"return { get a() { return 2; } };",
3135 5 * kPointerSize, 3141 5 * kPointerSize,
3136 1, 3142 1,
3137 30, 3143 31,
3138 { 3144 {
3139 B(LdaConstant), U8(0), // 3145 B(LdaConstant), U8(0), //
3140 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // 3146 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), //
3141 B(Star), R(0), // 3147 B(Star), R(0), //
3142 B(LdaConstant), U8(1), // 3148 B(LdaConstant), U8(1), //
3143 B(Star), R(1), // 3149 B(Star), R(1), //
3144 B(CreateClosure), U8(2), U8(0), // 3150 B(LdaConstant), U8(2), //
3151 B(CreateClosure), U8(0), //
3145 B(Star), R(2), // 3152 B(Star), R(2), //
3146 B(LdaNull), // 3153 B(LdaNull), //
3147 B(Star), R(3), // 3154 B(Star), R(3), //
3148 B(LdaZero), // 3155 B(LdaZero), //
3149 B(Star), R(4), // 3156 B(Star), R(4), //
3150 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), // 3157 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), //
3151 R(0), U8(5), // 3158 R(0), U8(5), //
3152 B(Ldar), R(0), // 3159 B(Ldar), R(0), //
3153 B(Return), // 3160 B(Return), //
3154 }, 3161 },
3155 3, 3162 3,
3156 {InstanceType::FIXED_ARRAY_TYPE, 3163 {InstanceType::FIXED_ARRAY_TYPE,
3157 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 3164 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
3158 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3165 InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3159 {"return { get a() { return this.x; }, set a(val) { this.x = val } };", 3166 {"return { get a() { return this.x; }, set a(val) { this.x = val } };",
3160 5 * kPointerSize, 3167 5 * kPointerSize,
3161 1, 3168 1,
3162 32, 3169 34,
3163 { 3170 {
3164 B(LdaConstant), U8(0), // 3171 B(LdaConstant), U8(0), //
3165 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // 3172 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), //
3166 B(Star), R(0), // 3173 B(Star), R(0), //
3167 B(LdaConstant), U8(1), // 3174 B(LdaConstant), U8(1), //
3168 B(Star), R(1), // 3175 B(Star), R(1), //
3169 B(CreateClosure), U8(2), U8(0), // 3176 B(LdaConstant), U8(2), //
3177 B(CreateClosure), U8(0), //
3170 B(Star), R(2), // 3178 B(Star), R(2), //
3171 B(CreateClosure), U8(3), U8(0), // 3179 B(LdaConstant), U8(3), //
3180 B(CreateClosure), U8(0), //
3172 B(Star), R(3), // 3181 B(Star), R(3), //
3173 B(LdaZero), // 3182 B(LdaZero), //
3174 B(Star), R(4), // 3183 B(Star), R(4), //
3175 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), // 3184 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), //
3176 R(0), U8(5), // 3185 R(0), U8(5), //
3177 B(Ldar), R(0), // 3186 B(Ldar), R(0), //
3178 B(Return), // 3187 B(Return), //
3179 }, 3188 },
3180 4, 3189 4,
3181 {InstanceType::FIXED_ARRAY_TYPE, 3190 {InstanceType::FIXED_ARRAY_TYPE,
3182 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 3191 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
3183 InstanceType::SHARED_FUNCTION_INFO_TYPE, 3192 InstanceType::SHARED_FUNCTION_INFO_TYPE,
3184 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3193 InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3185 {"return { set b(val) { this.y = val } };", 3194 {"return { set b(val) { this.y = val } };",
3186 5 * kPointerSize, 3195 5 * kPointerSize,
3187 1, 3196 1,
3188 30, 3197 31,
3189 { 3198 {
3190 B(LdaConstant), U8(0), // 3199 B(LdaConstant), U8(0), //
3191 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // 3200 B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), //
3192 B(Star), R(0), // 3201 B(Star), R(0), //
3193 B(LdaConstant), U8(1), // 3202 B(LdaConstant), U8(1), //
3194 B(Star), R(1), // 3203 B(Star), R(1), //
3195 B(LdaNull), // 3204 B(LdaNull), //
3196 B(Star), R(2), // 3205 B(Star), R(2), //
3197 B(CreateClosure), U8(2), U8(0), // 3206 B(LdaConstant), U8(2), //
3207 B(CreateClosure), U8(0), //
3198 B(Star), R(3), // 3208 B(Star), R(3), //
3199 B(LdaZero), // 3209 B(LdaZero), //
3200 B(Star), R(4), // 3210 B(Star), R(4), //
3201 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), // 3211 B(CallRuntime), U16(Runtime::kDefineAccessorPropertyUnchecked), //
3202 R(0), U8(5), // 3212 R(0), U8(5), //
3203 B(Ldar), R(0), // 3213 B(Ldar), R(0), //
3204 B(Return), // 3214 B(Return), //
3205 }, 3215 },
3206 3, 3216 3,
3207 {InstanceType::FIXED_ARRAY_TYPE, 3217 {InstanceType::FIXED_ARRAY_TYPE,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
3322 B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(1), U8(2), // 3332 B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(1), U8(2), //
3323 B(Ldar), R(1), // 3333 B(Ldar), R(1), //
3324 B(Return), // 3334 B(Return), //
3325 }, 3335 },
3326 2, 3336 2,
3327 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 3337 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
3328 InstanceType::FIXED_ARRAY_TYPE}}, 3338 InstanceType::FIXED_ARRAY_TYPE}},
3329 {"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };", 3339 {"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };",
3330 5 * kPointerSize, 3340 5 * kPointerSize,
3331 1, 3341 1,
3332 67, 3342 69,
3333 { 3343 {
3334 B(LdaConstant), U8(0), // 3344 B(LdaConstant), U8(0), //
3335 B(Star), R(0), // 3345 B(Star), R(0), //
3336 B(LdaConstant), U8(1), // 3346 B(LdaConstant), U8(1), //
3337 B(CreateObjectLiteral), U8(0), U8(simple_flags), // 3347 B(CreateObjectLiteral), U8(0), U8(simple_flags), //
3338 B(Star), R(1), // 3348 B(Star), R(1), //
3339 B(Ldar), R(0), // 3349 B(Ldar), R(0), //
3340 B(ToName), // 3350 B(ToName), //
3341 B(Star), R(2), // 3351 B(Star), R(2), //
3342 B(LdaConstant), U8(2), // 3352 B(LdaConstant), U8(2), //
3343 B(Star), R(3), // 3353 B(Star), R(3), //
3344 B(LdaZero), // 3354 B(LdaZero), //
3345 B(Star), R(4), // 3355 B(Star), R(4), //
3346 B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1), // 3356 B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1), //
3347 U8(4), // 3357 U8(4), //
3348 B(LdaConstant), U8(3), // 3358 B(LdaConstant), U8(3), //
3349 B(ToName), // 3359 B(ToName), //
3350 B(Star), R(2), // 3360 B(Star), R(2), //
3351 B(CreateClosure), U8(4), U8(0), // 3361 B(LdaConstant), U8(4), //
3362 B(CreateClosure), U8(0), //
3352 B(Star), R(3), // 3363 B(Star), R(3), //
3353 B(LdaZero), // 3364 B(LdaZero), //
3354 B(Star), R(4), // 3365 B(Star), R(4), //
3355 B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), // 3366 B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), //
3356 R(1), U8(4), // 3367 R(1), U8(4), //
3357 B(LdaConstant), U8(3), // 3368 B(LdaConstant), U8(3), //
3358 B(ToName), // 3369 B(ToName), //
3359 B(Star), R(2), // 3370 B(Star), R(2), //
3360 B(CreateClosure), U8(5), U8(0), // 3371 B(LdaConstant), U8(5), //
3372 B(CreateClosure), U8(0), //
3361 B(Star), R(3), // 3373 B(Star), R(3), //
3362 B(LdaZero), // 3374 B(LdaZero), //
3363 B(Star), R(4), // 3375 B(Star), R(4), //
3364 B(CallRuntime), U16(Runtime::kDefineSetterPropertyUnchecked), // 3376 B(CallRuntime), U16(Runtime::kDefineSetterPropertyUnchecked), //
3365 R(1), U8(4), // 3377 R(1), U8(4), //
3366 B(Ldar), R(1), // 3378 B(Ldar), R(1), //
3367 B(Return), // 3379 B(Return), //
3368 }, 3380 },
3369 6, 3381 6,
3370 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 3382 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
(...skipping 16 matching lines...) Expand all
3387 InitializedHandleScope handle_scope; 3399 InitializedHandleScope handle_scope;
3388 BytecodeGeneratorHelper helper; 3400 BytecodeGeneratorHelper helper;
3389 3401
3390 int has_function_flags = ObjectLiteral::kFastElements | 3402 int has_function_flags = ObjectLiteral::kFastElements |
3391 ObjectLiteral::kHasFunction | 3403 ObjectLiteral::kHasFunction |
3392 ObjectLiteral::kDisableMementos; 3404 ObjectLiteral::kDisableMementos;
3393 ExpectedSnippet<InstanceType> snippets[] = { 3405 ExpectedSnippet<InstanceType> snippets[] = {
3394 {"var a = { func: function() { } };", 3406 {"var a = { func: function() { } };",
3395 5 * kPointerSize, 3407 5 * kPointerSize,
3396 1, 3408 1,
3397 49, 3409 50,
3398 { 3410 {
3399 B(LdaConstant), U8(0), // 3411 B(LdaConstant), U8(0), //
3400 B(Star), R(1), // 3412 B(Star), R(1), //
3401 B(LdaZero), // 3413 B(LdaZero), //
3402 B(Star), R(2), // 3414 B(Star), R(2), //
3403 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // 3415 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), //
3404 B(LdaConstant), U8(1), // 3416 B(LdaConstant), U8(1), //
3405 B(Star), R(1), // 3417 B(Star), R(1), //
3406 B(LdaZero), // 3418 B(LdaZero), //
3407 B(Star), R(2), // 3419 B(Star), R(2), //
3408 B(LdaConstant), U8(2), // 3420 B(LdaConstant), U8(2), //
3409 B(CreateObjectLiteral), U8(0), U8(has_function_flags), // 3421 B(CreateObjectLiteral), U8(0), U8(has_function_flags), //
3410 B(Star), R(4), // 3422 B(Star), R(4), //
3411 B(CreateClosure), U8(4), U8(1), // 3423 B(LdaConstant), U8(4), //
3424 B(CreateClosure), U8(1), //
3412 B(StoreICSloppy), R(4), U8(3), U8(5), // 3425 B(StoreICSloppy), R(4), U8(3), U8(5), //
3413 B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1), // 3426 B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1), //
3414 B(Ldar), R(4), // 3427 B(Ldar), R(4), //
3415 B(Star), R(3), // 3428 B(Star), R(3), //
3416 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3), // 3429 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3), //
3417 B(LdaUndefined), // 3430 B(LdaUndefined), //
3418 B(Return), // 3431 B(Return), //
3419 }, 3432 },
3420 5, 3433 5,
3421 {InstanceType::FIXED_ARRAY_TYPE, 3434 {InstanceType::FIXED_ARRAY_TYPE,
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 3656
3644 Handle<i::TypeFeedbackVector> vector = 3657 Handle<i::TypeFeedbackVector> vector =
3645 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 3658 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
3646 3659
3647 int closure = Register::function_closure().index(); 3660 int closure = Register::function_closure().index();
3648 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 3661 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
3649 ExpectedSnippet<InstanceType> snippets[] = { 3662 ExpectedSnippet<InstanceType> snippets[] = {
3650 {"var a; return function() { a = 1; };", 3663 {"var a; return function() { a = 1; };",
3651 1 * kPointerSize, 3664 1 * kPointerSize,
3652 1, 3665 1,
3653 11, 3666 12,
3654 { 3667 {
3655 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3668 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3656 R(closure), U8(1), // 3669 R(closure), U8(1), //
3657 B(PushContext), R(0), // 3670 B(PushContext), R(0), //
3658 B(CreateClosure), U8(0), U8(0), // 3671 B(LdaConstant), U8(0), //
3672 B(CreateClosure), U8(0), //
3659 B(Return), // 3673 B(Return), //
3660 }, 3674 },
3661 1, 3675 1,
3662 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3676 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3663 {"var a = 1; return function() { a = 2; };", 3677 {"var a = 1; return function() { a = 2; };",
3664 1 * kPointerSize, 3678 1 * kPointerSize,
3665 1, 3679 1,
3666 16, 3680 17,
3667 { 3681 {
3668 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3682 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3669 R(closure), U8(1), // 3683 R(closure), U8(1), //
3670 B(PushContext), R(0), // 3684 B(PushContext), R(0), //
3671 B(LdaSmi8), U8(1), // 3685 B(LdaSmi8), U8(1), //
3672 B(StaContextSlot), R(0), U8(first_context_slot), // 3686 B(StaContextSlot), R(0), U8(first_context_slot), //
3673 B(CreateClosure), U8(0), U8(0), // 3687 B(LdaConstant), U8(0), //
3688 B(CreateClosure), U8(0), //
3674 B(Return), // 3689 B(Return), //
3675 }, 3690 },
3676 1, 3691 1,
3677 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3692 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3678 {"var a = 1; var b = 2; return function() { a = 2; b = 3 };", 3693 {"var a = 1; var b = 2; return function() { a = 2; b = 3 };",
3679 1 * kPointerSize, 3694 1 * kPointerSize,
3680 1, 3695 1,
3681 21, 3696 22,
3682 { 3697 {
3683 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3698 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3684 R(closure), U8(1), // 3699 R(closure), U8(1), //
3685 B(PushContext), R(0), // 3700 B(PushContext), R(0), //
3686 B(LdaSmi8), U8(1), // 3701 B(LdaSmi8), U8(1), //
3687 B(StaContextSlot), R(0), U8(first_context_slot), // 3702 B(StaContextSlot), R(0), U8(first_context_slot), //
3688 B(LdaSmi8), U8(2), // 3703 B(LdaSmi8), U8(2), //
3689 B(StaContextSlot), R(0), U8(first_context_slot + 1), // 3704 B(StaContextSlot), R(0), U8(first_context_slot + 1), //
3690 B(CreateClosure), U8(0), U8(0), // 3705 B(LdaConstant), U8(0), //
3706 B(CreateClosure), U8(0), //
3691 B(Return), // 3707 B(Return), //
3692 }, 3708 },
3693 1, 3709 1,
3694 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3710 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3695 {"var a; (function() { a = 2; })(); return a;", 3711 {"var a; (function() { a = 2; })(); return a;",
3696 3 * kPointerSize, 3712 3 * kPointerSize,
3697 1, 3713 1,
3698 24, 3714 25,
3699 { 3715 {
3700 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3716 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3701 R(closure), U8(1), // 3717 R(closure), U8(1), //
3702 B(PushContext), R(0), // 3718 B(PushContext), R(0), //
3703 B(LdaUndefined), // 3719 B(LdaUndefined), //
3704 B(Star), R(2), // 3720 B(Star), R(2), //
3705 B(CreateClosure), U8(0), U8(0), // 3721 B(LdaConstant), U8(0), //
3722 B(CreateClosure), U8(0), //
3706 B(Star), R(1), // 3723 B(Star), R(1), //
3707 B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot)), // 3724 B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot)), //
3708 B(LdaContextSlot), R(0), U8(first_context_slot), // 3725 B(LdaContextSlot), R(0), U8(first_context_slot), //
3709 B(Return), // 3726 B(Return), //
3710 }, 3727 },
3711 1, 3728 1,
3712 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3729 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3713 {"'use strict'; let a = 1; { let b = 2; return function() { a + b; }; }", 3730 {"'use strict'; let a = 1; { let b = 2; return function() { a + b; }; }",
3714 4 * kPointerSize, 3731 4 * kPointerSize,
3715 1, 3732 1,
3716 44, 3733 45,
3717 { 3734 {
3718 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3735 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3719 R(closure), U8(1), // 3736 R(closure), U8(1), //
3720 B(PushContext), R(0), // 3737 B(PushContext), R(0), //
3721 B(LdaTheHole), // 3738 B(LdaTheHole), //
3722 B(StaContextSlot), R(0), U8(first_context_slot), // 3739 B(StaContextSlot), R(0), U8(first_context_slot), //
3723 B(LdaSmi8), U8(1), // 3740 B(LdaSmi8), U8(1), //
3724 B(StaContextSlot), R(0), U8(first_context_slot), // 3741 B(StaContextSlot), R(0), U8(first_context_slot), //
3725 B(LdaConstant), U8(0), // 3742 B(LdaConstant), U8(0), //
3726 B(Star), R(2), // 3743 B(Star), R(2), //
3727 B(Ldar), R(closure), // 3744 B(Ldar), R(closure), //
3728 B(Star), R(3), // 3745 B(Star), R(3), //
3729 B(CallRuntime), U16(Runtime::kPushBlockContext), R(2), U8(2), // 3746 B(CallRuntime), U16(Runtime::kPushBlockContext), R(2), U8(2), //
3730 B(PushContext), R(1), // 3747 B(PushContext), R(1), //
3731 B(LdaTheHole), // 3748 B(LdaTheHole), //
3732 B(StaContextSlot), R(1), U8(first_context_slot), // 3749 B(StaContextSlot), R(1), U8(first_context_slot), //
3733 B(LdaSmi8), U8(2), // 3750 B(LdaSmi8), U8(2), //
3734 B(StaContextSlot), R(1), U8(first_context_slot), // 3751 B(StaContextSlot), R(1), U8(first_context_slot), //
3735 B(CreateClosure), U8(1), U8(0), // 3752 B(LdaConstant), U8(1), //
3753 B(CreateClosure), U8(0), //
3736 B(Return), // 3754 B(Return), //
3737 }, 3755 },
3738 2, 3756 2,
3739 {InstanceType::FIXED_ARRAY_TYPE, 3757 {InstanceType::FIXED_ARRAY_TYPE,
3740 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3758 InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3741 }; 3759 };
3742 3760
3743 for (size_t i = 0; i < arraysize(snippets); i++) { 3761 for (size_t i = 0; i < arraysize(snippets); i++) {
3744 Handle<BytecodeArray> bytecode_array = 3762 Handle<BytecodeArray> bytecode_array =
3745 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 3763 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
3746 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 3764 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
3747 } 3765 }
3748 } 3766 }
3749 3767
3750 3768
3751 TEST(ContextParameters) { 3769 TEST(ContextParameters) {
3752 InitializedHandleScope handle_scope; 3770 InitializedHandleScope handle_scope;
3753 BytecodeGeneratorHelper helper; 3771 BytecodeGeneratorHelper helper;
3754 3772
3755 int closure = Register::function_closure().index(); 3773 int closure = Register::function_closure().index();
3756 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 3774 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
3757 3775
3758 ExpectedSnippet<InstanceType> snippets[] = { 3776 ExpectedSnippet<InstanceType> snippets[] = {
3759 {"function f(arg1) { return function() { arg1 = 2; }; }", 3777 {"function f(arg1) { return function() { arg1 = 2; }; }",
3760 1 * kPointerSize, 3778 1 * kPointerSize,
3761 2, 3779 2,
3762 16, 3780 17,
3763 { 3781 {
3764 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3782 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3765 R(closure), U8(1), // 3783 R(closure), U8(1), //
3766 B(PushContext), R(0), // 3784 B(PushContext), R(0), //
3767 B(Ldar), R(helper.kLastParamIndex), // 3785 B(Ldar), R(helper.kLastParamIndex), //
3768 B(StaContextSlot), R(0), U8(first_context_slot), // 3786 B(StaContextSlot), R(0), U8(first_context_slot), //
3769 B(CreateClosure), U8(0), U8(0), // 3787 B(LdaConstant), U8(0), //
3788 B(CreateClosure), U8(0), //
3770 B(Return), // 3789 B(Return), //
3771 }, 3790 },
3772 1, 3791 1,
3773 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3792 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3774 {"function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }", 3793 {"function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }",
3775 2 * kPointerSize, 3794 2 * kPointerSize,
3776 2, 3795 2,
3777 21, 3796 22,
3778 { 3797 {
3779 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3798 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3780 R(closure), U8(1), // 3799 R(closure), U8(1), //
3781 B(PushContext), R(1), // 3800 B(PushContext), R(1), //
3782 B(Ldar), R(helper.kLastParamIndex), // 3801 B(Ldar), R(helper.kLastParamIndex), //
3783 B(StaContextSlot), R(1), U8(first_context_slot), // 3802 B(StaContextSlot), R(1), U8(first_context_slot), //
3784 B(CreateClosure), U8(0), U8(0), // 3803 B(LdaConstant), U8(0), //
3804 B(CreateClosure), U8(0), //
3785 B(Star), R(0), // 3805 B(Star), R(0), //
3786 B(LdaContextSlot), R(1), U8(first_context_slot), // 3806 B(LdaContextSlot), R(1), U8(first_context_slot), //
3787 B(Return), // 3807 B(Return), //
3788 }, 3808 },
3789 1, 3809 1,
3790 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3810 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3791 {"function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }", 3811 {"function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }",
3792 1 * kPointerSize, 3812 1 * kPointerSize,
3793 5, 3813 5,
3794 21, 3814 22,
3795 { 3815 {
3796 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3816 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3797 R(closure), U8(1), // 3817 R(closure), U8(1), //
3798 B(PushContext), R(0), // 3818 B(PushContext), R(0), //
3799 B(Ldar), R(helper.kLastParamIndex - 3), // 3819 B(Ldar), R(helper.kLastParamIndex - 3), //
3800 B(StaContextSlot), R(0), U8(first_context_slot + 1), // 3820 B(StaContextSlot), R(0), U8(first_context_slot + 1), //
3801 B(Ldar), R(helper.kLastParamIndex -1), // 3821 B(Ldar), R(helper.kLastParamIndex -1), //
3802 B(StaContextSlot), R(0), U8(first_context_slot), // 3822 B(StaContextSlot), R(0), U8(first_context_slot), //
3803 B(CreateClosure), U8(0), U8(0), // 3823 B(LdaConstant), U8(0), //
3824 B(CreateClosure), U8(0), //
3804 B(Return), // 3825 B(Return), //
3805 }, 3826 },
3806 1, 3827 1,
3807 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3828 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3808 {"function f() { var self = this; return function() { self = 2; }; }", 3829 {"function f() { var self = this; return function() { self = 2; }; }",
3809 1 * kPointerSize, 3830 1 * kPointerSize,
3810 1, 3831 1,
3811 16, 3832 17,
3812 { 3833 {
3813 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 3834 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
3814 R(closure), U8(1), // 3835 R(closure), U8(1), //
3815 B(PushContext), R(0), // 3836 B(PushContext), R(0), //
3816 B(Ldar), R(helper.kLastParamIndex), // 3837 B(Ldar), R(helper.kLastParamIndex), //
3817 B(StaContextSlot), R(0), U8(first_context_slot), // 3838 B(StaContextSlot), R(0), U8(first_context_slot), //
3818 B(CreateClosure), U8(0), U8(0), // 3839 B(LdaConstant), U8(0), //
3840 B(CreateClosure), U8(0), //
3819 B(Return), // 3841 B(Return), //
3820 }, 3842 },
3821 1, 3843 1,
3822 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 3844 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3823 }; 3845 };
3824 3846
3825 for (size_t i = 0; i < arraysize(snippets); i++) { 3847 for (size_t i = 0; i < arraysize(snippets); i++) {
3826 Handle<BytecodeArray> bytecode_array = 3848 Handle<BytecodeArray> bytecode_array =
3827 helper.MakeBytecodeForFunction(snippets[i].code_snippet); 3849 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
3828 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 3850 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
4046 B(Inc), // 4068 B(Inc), //
4047 B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)), // 4069 B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)), //
4048 B(Return), // 4070 B(Return), //
4049 }, 4071 },
4050 2, 4072 2,
4051 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, 4073 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
4052 InstanceType::FIXED_ARRAY_TYPE}}, 4074 InstanceType::FIXED_ARRAY_TYPE}},
4053 {"var a = 1; var b = function() { return a }; return ++a;", 4075 {"var a = 1; var b = function() { return a }; return ++a;",
4054 2 * kPointerSize, 4076 2 * kPointerSize,
4055 1, 4077 1,
4056 26, 4078 27,
4057 { 4079 {
4058 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // 4080 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
4059 U8(1), // 4081 U8(1), //
4060 B(PushContext), R(1), // 4082 B(PushContext), R(1), //
4061 B(LdaSmi8), U8(1), // 4083 B(LdaSmi8), U8(1), //
4062 B(StaContextSlot), R(1), U8(first_context_slot), // 4084 B(StaContextSlot), R(1), U8(first_context_slot), //
4063 B(CreateClosure), U8(0), U8(0), // 4085 B(LdaConstant), U8(0), //
4086 B(CreateClosure), U8(0), //
4064 B(Star), R(0), // 4087 B(Star), R(0), //
4065 B(LdaContextSlot), R(1), U8(first_context_slot), // 4088 B(LdaContextSlot), R(1), U8(first_context_slot), //
4066 B(ToNumber), // 4089 B(ToNumber), //
4067 B(Inc), // 4090 B(Inc), //
4068 B(StaContextSlot), R(1), U8(first_context_slot), // 4091 B(StaContextSlot), R(1), U8(first_context_slot), //
4069 B(Return), // 4092 B(Return), //
4070 }, 4093 },
4071 1, 4094 1,
4072 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 4095 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
4073 {"var a = 1; var b = function() { return a }; return a--;", 4096 {"var a = 1; var b = function() { return a }; return a--;",
4074 3 * kPointerSize, 4097 3 * kPointerSize,
4075 1, 4098 1,
4076 30, 4099 31,
4077 { 4100 {
4078 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // 4101 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
4079 U8(1), // 4102 U8(1), //
4080 B(PushContext), R(1), // 4103 B(PushContext), R(1), //
4081 B(LdaSmi8), U8(1), // 4104 B(LdaSmi8), U8(1), //
4082 B(StaContextSlot), R(1), U8(first_context_slot), // 4105 B(StaContextSlot), R(1), U8(first_context_slot), //
4083 B(CreateClosure), U8(0), U8(0), // 4106 B(LdaConstant), U8(0), //
4107 B(CreateClosure), U8(0), //
4084 B(Star), R(0), // 4108 B(Star), R(0), //
4085 B(LdaContextSlot), R(1), U8(first_context_slot), // 4109 B(LdaContextSlot), R(1), U8(first_context_slot), //
4086 B(ToNumber), // 4110 B(ToNumber), //
4087 B(Star), R(2), // 4111 B(Star), R(2), //
4088 B(Dec), // 4112 B(Dec), //
4089 B(StaContextSlot), R(1), U8(first_context_slot), // 4113 B(StaContextSlot), R(1), U8(first_context_slot), //
4090 B(Ldar), R(2), // 4114 B(Ldar), R(2), //
4091 B(Return), // 4115 B(Return), //
4092 }, 4116 },
4093 1, 4117 1,
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
4283 B(BitwiseXor), R(2), // 4307 B(BitwiseXor), R(2), //
4284 B(KeyedStoreICSloppy), R(0), R(1), U8(vector->GetIndex(slot2)), // 4308 B(KeyedStoreICSloppy), R(0), R(1), U8(vector->GetIndex(slot2)), //
4285 B(LdaUndefined), // 4309 B(LdaUndefined), //
4286 B(Return), // 4310 B(Return), //
4287 }, 4311 },
4288 1, 4312 1,
4289 {InstanceType::FIXED_ARRAY_TYPE}}, 4313 {InstanceType::FIXED_ARRAY_TYPE}},
4290 {"var a = 1; (function f() { return a; }); a |= 24;", 4314 {"var a = 1; (function f() { return a; }); a |= 24;",
4291 2 * kPointerSize, 4315 2 * kPointerSize,
4292 1, 4316 1,
4293 29, 4317 30,
4294 { 4318 {
4295 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // 4319 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
4296 U8(1), // 4320 U8(1), //
4297 B(PushContext), R(0), // 4321 B(PushContext), R(0), //
4298 B(LdaSmi8), U8(1), // 4322 B(LdaSmi8), U8(1), //
4299 B(StaContextSlot), R(0), U8(first_context_slot), // 4323 B(StaContextSlot), R(0), U8(first_context_slot), //
4300 B(CreateClosure), U8(0), U8(0), // 4324 B(LdaConstant), U8(0), //
4325 B(CreateClosure), U8(0), //
4301 B(LdaContextSlot), R(0), U8(first_context_slot), // 4326 B(LdaContextSlot), R(0), U8(first_context_slot), //
4302 B(Star), R(1), // 4327 B(Star), R(1), //
4303 B(LdaSmi8), U8(24), // 4328 B(LdaSmi8), U8(24), //
4304 B(BitwiseOr), R(1), // 4329 B(BitwiseOr), R(1), //
4305 B(StaContextSlot), R(0), U8(first_context_slot), // 4330 B(StaContextSlot), R(0), U8(first_context_slot), //
4306 B(LdaUndefined), // 4331 B(LdaUndefined), //
4307 B(Return), // 4332 B(Return), //
4308 }, 4333 },
4309 1, 4334 1,
4310 {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, 4335 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after
5454 for (size_t i = 0; i < arraysize(snippets); i++) { 5479 for (size_t i = 0; i < arraysize(snippets); i++) {
5455 Handle<BytecodeArray> bytecode_array = 5480 Handle<BytecodeArray> bytecode_array =
5456 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 5481 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
5457 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 5482 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
5458 } 5483 }
5459 } 5484 }
5460 5485
5461 } // namespace interpreter 5486 } // namespace interpreter
5462 } // namespace internal 5487 } // namespace internal
5463 } // namespace v8 5488 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-run-bytecode-graph-builder.cc ('k') | test/unittests/compiler/bytecode-graph-builder-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698